Порядок вложенных циклов Postgres - PullRequest
1 голос
/ 05 мая 2011

У меня следующий запрос:

SELECT t1.c1 FROM t1,t2 WHERE t1.c2 = 'X' AND t1.id = t2.id AND t2.c3 = 'Y';

Postgres создает два плана для этого запроса, например:

Nested Loop (rows=1 width=7) (actual rows=1 loops=1)
    -> Index Scan using idx1 on t1 (rows=1 width=7) (actual rows=4 loops=1)
    -> Index Scan using idx2 on t2 (rows=1 width=7) (actual rows=0 loops=7)

или:

Nested Loop (rows=1 width=7) (actual rows=1 loops=1)
    -> Index Scan using idx2 on t2 (rows=4 width=7) (actual rows=1000000 loops=1)
    -> Index Scan using idx1 on t1 (rows=1 width=7) (actual rows=0 loops=1000000)

Итакиногда для внешнего цикла выбирается t1, иногда t2.И если выбран второй план, производительность просто ужасна.

Мой вопрос: как я могу заставить Postgres всегда использовать первый план запроса с t1 во внешнем цикле?

Ответы [ 2 ]

1 голос
/ 05 мая 2011

Убедитесь, что вы используете ANALYZE на регулярной основе. Оценки далеко.

Кстати, Postgres будет вероятно все равно, но вы могли бы получить лучшие результаты с

SELECT T1.c1 FROM t1 JOIN t2 ON t1.id=t2.id
WHERE t1.c2='X' AND t2.c3='Y';
0 голосов
/ 08 мая 2011

Пытался использовать левое соединение? Это должно заставить порядок соединения и вернуть тот же результат из-за предложения на t2.c3:

SELECT t1.c1
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.c2 = 'X' AND t2.c3 = 'Y';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...