Я використовую наступні рекурсивні CTE як мінімальний приклад, але в цілому оптимізатор повинен використовувати "здогадані" кардинальності для рекурсивних CTE:
with recursive w(n) as ( select 1 union all select n+1 from w where n<5 ) select * from w;
/*
n
---
1
2
3
4
5
*/
explain analyze
with recursive w(n) as ( select 1 union all select n+1 from w where n<5 ) select * from w;
/*
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
CTE Scan on w (cost=2.95..3.57 rows=31 width=4) (actual time=0.005..0.020 rows=5 loops=1)
CTE w
-> Recursive Union (cost=0.00..2.95 rows=31 width=4) (actual time=0.003..0.017 rows=5 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
-> WorkTable Scan on w w_1 (cost=0.00..0.23 rows=3 width=4) (actual time=0.002..0.002 rows=1 loops=5)
Filter: (n < 5)
Rows Removed by Filter: 0
*/
Зверніть увагу на rows=31
оцінені та rows=5
фактичні кардинальності у вищезгаданому плані. У деяких випадках 100, здається, використовуються як оцінка, я не впевнений у точній логіці за здогадами.
У моїй проблемі в реальному світі погана оцінка кардинальності не дозволяє вибирати швидкий план "вкладених циклів". Як я можу "натякнути" на кардинальність оптимізатора для рекурсивного CTE, щоб обійти це?
COST
функції, але не багато іншого. Я б запропонував підняти його на pgsql-хакерів, але ви просто зачепилися б за нову ітерацію дебатів про "натяки", витрачаючи маси гарячого повітря і нічого не досягаючи :-(