Closed rhomboss closed 7 months ago
I'm sorry, but I don't have much insight into how the extra CTE will impact performance. My basic understanding is that you can run into problems when you have too many nested CTEs because it will start to confuse the SQL engine. But one nested CTE is probably not too many.
Additionally, depending on the underlying data having the extra CTE could be more efficient than the standalone. For example #50 , if we were to add a WHERE
statement to the __rank_table
CTE to filter based on user_id we could increase performance by reducing the overall number of nodes that need to be traversed when constructing the __tree
.
Re. filtering: Ah yes, this is an excellent point. I still have the hope that PostgreSQL will stop treating recursive CTEs as optimization fences at some point in the future. For the time being most trees I have are so small that it's not really a problem anyway.
Also, we could use a materialized view or something for the rank table and even the recursive table in the future if it's a problem. For now I'm going to merge this and upload a new release shortly. Thanks for your great work!
Addresses #6.
Uses the
ROW_NUMBER()
window expression to map any ordering criteria onto an ascending set of ordinal integers which can be used to properly order a tree.Parameters for this new ordering method are generated by
get_sibling_order_params()
which uses the base DjangoSQLCompiler
to convert a dummy Django queryset object to SQL. This way we are able to rely on Django's backend to generate the extra SQL needed for more complex orderings like ordering by a related field.This change will also make supporting additional forms of ordering simpler. For example, ordering based on annotations is not currently supported. However, it could be added by having
TreeQuerySet
override the baseannotate()
method so that it additionally stores its initialargs
andkwargs
as instance variables which can later be submitted to the dummy queryset used to generate ordering parameters.