|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Добрый день. Ребята, прошу помочь разобраться с принципами работы оптимизатора в данной ситуации. Есть таблица t_Form2User(id_form, id_user), которая связывает формы и пользователей. на id_form навешан индекс. Выполняю два запроса. Код: sql 1. 2. 3. 4.
Второй Код: sql 1. 2. 3. 4.
В первом запросе cte возвращает те же 5 id форм. Было предположение, что в первом запросе оптимизатор материализует CTE и потом используя индекс по t_Form2User.id_form сходит к таблице t_Form2User. Но получилось, что в первом запросе мы получаем фулскан таблицы t_Form2User, а во втором запросе он ходит в t_Form2User по индексу id_form. Понятно, что на поведение оптимизатора влияет наличие OR в CTE. Как работает оптимизатор в данном случае? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 08:57 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Покажите оба плана запросов. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 10:39 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
kliff, 1)надо оба плана показать 2)указать какая версия (потому что поведение между 12 версией и более старыми - для CTE отличается сильно). ... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 11:10 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Maxim Boguk kliff, 1)надо оба плана показать 2)указать какая версия (потому что поведение между 12 версией и более старыми - для CTE отличается сильно). Версия 9.6 Индекс он же pk CONSTRAINT t_Form2User_pk PRIMARY KEY (id_form, id_user) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 14:16 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Могу предположить, что имея конкретные значения id = ANY ('{4415, 4416, 4417, 4418, 4419}' планировщик может посмотреть по ним статистику и сделать более точное предположение о количестве результирующих строк. И соответственно принять решение, смотреть по индексу или всю таблицу. В первом запросе планировщик предполагает получить rows=10798 Код: sql 1.
А во втором rows=4 Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 15:25 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
kliff, А если так? Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.05.2020, 19:40 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Swa111 kliff, А если так? Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
Такой запрос я пробовал, он по индексам отрабатывает. Но у меня все-таки вопрос не как переписать запрос, а прояснить работу оптимизатора на конкретных примерах чтобы избавиться от недопонимания. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2020, 15:17 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
kliff, В первом случае оптимизатор думает что он получит -> CTE Scan on forms (cost=0.00..215.96 rows=10798 width=4) 10800 строк из CTE а во втором случае думает что получит -> CTE Scan on forms (cost=0.00..0.08 rows=4 width=4) И исходя из своей статистики по таблице t_Form2User решает что в первом случае join будет быстрее сделать через hash join потому что надо join нить с 2500 большим количеством строк. cte тут влияет достаточно слабо... с тем же успехом можно и без cte а с обычным подзапросом получить тот же эффект. Проблема в оценке количества строк по OR условию, она всегда почти проблемная. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.05.2020, 03:18 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
Большое всем спасибо за участие. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.05.2020, 09:57 |
|
Оптимизатор и CTE
|
|||
---|---|---|---|
#18+
kliff, добавлю, что постриг еще дает интересные эффекты если вместо where id_form in (select id from forms_ids); писать where id_form = any (array(select id from forms_ids)); часто это приводит к тому, что начинает использоваться индекс ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2020, 15:14 |
|
|
start [/forum/topic.php?fid=53&gotonew=1&tid=1994679]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
41ms |
get topic data: |
13ms |
get first new msg: |
8ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
2ms |
others: | 277ms |
total: | 433ms |
0 / 0 |