|
|
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Добрый день, Подскажите, почему так - есть 2 таблицы c несколькими тысячами записей и индексом: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. После этого немного тюнинга и апдэйт статистики: Код: plsql 1. 2. 3. И делаю идентичные запросы с разницой INNER JOIN vs LEFT OUTER LOIN: Код: plsql 1. 2. 3. 'Nested Loop (cost=20000000000.04..20000008170.60 rows=2004 width=32) (actual time=0.079..25.214 rows=2002 loops=1)' ' -> Seq Scan on b (cost=10000000000.00..10000000042.02 rows=2002 width=12) (actual time=0.031..0.663 rows=2002 loops=1)' ' -> Bitmap Heap Scan on a (cost=0.04..4.05 rows=1 width=20) (actual time=0.010..0.010 rows=1 loops=2002)' ' Recheck Cond: (names @> b.name)' ' Heap Blocks: exact=2002' ' -> Bitmap Index Scan on a_names_idx1 (cost=0.00..0.04 rows=1 width=0) (actual time=0.006..0.006 rows=1 loops=2002)' ' Index Cond: (names @> b.name)' 'Planning time: 0.196 ms' 'Execution time: 25.583 ms' и Код: plsql 1. 2. 3. 'Nested Loop Left Join (cost=30000000000.00..30000030134.07 rows=2004 width=32) (actual time=0.077..1793.021 rows=2002 loops=1)' ' Join Filter: (a.names @> b.name)' ' Rows Removed by Join Filter: 2002000' ' -> Seq Scan on a (cost=10000000000.00..10000000027.01 rows=1001 width=20) (actual time=0.033..0.439 rows=1001 loops=1)' ' -> Materialize (cost=10000000000.00..10000000052.03 rows=2002 width=12) (actual time=0.000..0.226 rows=2002 loops=1001)' ' -> Seq Scan on b (cost=10000000000.00..10000000042.02 rows=2002 width=12) (actual time=0.024..0.378 rows=2002 loops=1)' 'Planning time: 0.156 ms' 'Execution time: 1793.319 ms' В обоих случаях результат 2002 записей, но из-за того что LEFT OUTER JOIN не использует индекс запрос выполняется в тысячу раз медленнее. Подскажите как побороть? И почему планировщик не пользует индекс когда он есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 17:09 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
bemtaill, Потому что внешняя связка "склоняет" планировщик к единственному варианту исполнения запроса: When the query involves outer joins, the planner has less freedom than it does for plain (inner) joins. Сравните таблицы во внешней и внутренней частях обеих связок, а также значения `loops`. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 17:22 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
vyegorovbemtaill, Потому что внешняя связка "склоняет" планировщик к единственному варианту исполнения запроса: When the query involves outer joins, the planner has less freedom than it does for plain (inner) joins. ... Там вроде про порядок в котором таблицы джойнятся, а у меня только 2 таблицы. Идея в том что мне необходим быстрый LEFT OUTER JOIN, так как на самом деле таблица a может содержать names=null и мне надо получить все записи из a независимо от записей в b . Это вообще реально?:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 17:36 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
bemtaill, Тут если бы и помог индекс, то только при условии того, что он построен по таблице B. Таблица A без условий фильтрации по ней в любом случае будет читаться полностью, так как наличия ВСЕХ записей из неё требует тот факт, что она является ГЛАВНОЙ таблицей в левом соединении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 17:53 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
bemtaill, что за выёживание, хранить в таблицах неструктурированные данные и колоться, но продолжать упорно лезть на structured query language. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 18:04 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
p2., это жизнь:) рефакторинг выливается в довольно "дорогостоющую" процедуру, поэтому пока пытаемся решить вопрос по другому с тем чтобы в след году сделать по "правильному". Щукина Анна, В реальном запросе есть фильтр на A который отсеивает ~ половину строк из А, все равно медленно. Индекс в B тоже не помогает. vyegorov, Я кажется понял, что вы имели ввиду: при INNER JOIN пранеровщик присоединяет А к В, тогда как при LEFT JOIN он не имеет такой возможности и вынужден присоединять В к А. Попробовал увеличить количество записей в таблицах, проапдейтить статистику, не помогло. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 18:38 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
bemtaillВ реальном запросе есть фильтр на A который отсеивает ~ половину строк из А, все равно медленно... И план тот же самый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 18:40 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
bemtaillvyegorovbemtaill, Потому что внешняя связка "склоняет" планировщик к единственному варианту исполнения запроса: пропущено... ... Там вроде про порядок в котором таблицы джойнятся, а у меня только 2 таблицы. Идея в том что мне необходим быстрый LEFT OUTER JOIN, так как на самом деле таблица a может содержать names=null и мне надо получить все записи из a независимо от записей в b . Это вообще реально?:) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. не? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 18:48 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Lonepsycho Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Вторая часть должна выбирать всё из `a`, что не содержится в `b`: Код: sql 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2015, 22:37 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
А этот мега хинт зачем???? авторSET enable_nestloop = off; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2015, 09:17 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Щукина Аннаbemtaill, Тут если бы и помог индекс, то только при условии того, что он построен по таблице B. Таблица A без условий фильтрации по ней в любом случае будет читаться полностью, так как наличия ВСЕХ записей из неё требует тот факт, что она является ГЛАВНОЙ таблицей в левом соединении. кстати давно пора ПГ допилить напильником. У (некоторых) конкурентов есть возможность в NL left join делать главной любую таблицу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2015, 09:19 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Спасибо всем за помощь, разобрался ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2015, 13:19 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Ivan DurakУ (некоторых) конкурентов есть возможность в NL left join делать главной любую таблицу.пример планов можешь привести? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.12.2015, 03:26 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
p2.Ivan DurakУ (некоторых) конкурентов есть возможность в NL left join делать главной любую таблицу.пример планов можешь привести? Очень сомневаюсь что так физически возможно (для merge/hash join дело другое но вот nestloop LJ с ведущей таблицей на стороне LJ у меня как то ну совсем не вырисовывается алгоритм). -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.12.2015, 05:48 |
|
||
|
LEFT OUTER JOIN не использует индекс
|
|||
|---|---|---|---|
|
#18+
Maxim Bogukp2.пропущено... пример планов можешь привести? Очень сомневаюсь что так физически возможно (для merge/hash join дело другое но вот nestloop LJ с ведущей таблицей на стороне LJ у меня как то ну совсем не вырисовывается алгоритм). -- Maxim Boguk www.postgresql-consulting.ru согласен, прогнал. То было про HJ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.12.2015, 12:06 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=39131479&tid=1997561]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
187ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
52ms |
get tp. blocked users: |
1ms |
| others: | 227ms |
| total: | 505ms |

| 0 / 0 |
