Каковы подводные камни установки enable_nestloop в положение OFF
У меня есть запрос в моем приложении, который выполняется очень быстро, когда в моих таблицах большое количество строк. Но когда число строк является умеренным (ни большим, ни малым), тот же запрос работает в 15 раз медленнее.
План объяснения показывает, что запрос в наборе данных среднего размера использует вложенные циклы для его алгоритма соединения. В большом наборе данных используются хешированные соединения.
Я могу отказать планировщику запросов от использования вложенных циклов либо на уровне базы данных (postgresql.conf), либо за сеанс (SET enable_nestloop TO off
).
Каковы потенциальные ловушки SET enable_nestloop TO off
?
Дополнительная информация: PostgreSQL 8.2.6, работающая под Windows.
Ответы
Ответ 1
Каковы потенциальные ловушки установки enable_nestloop
на off
?
Это означает, что вы никогда не сможете эффективно использовать индексы.
И кажется, что вы не используете их сейчас.
Запрос такой:
SELECT u.name, p.name
FROM users u
JOIN profiles p ON p.id = u.profile_id
WHERE u.id = :id
скорее всего, будет использовать NESTED LOOPS
с INDEX SCAN
на user.id
и INDEX SCAN
на profile.id
при условии, что вы создали индексы в этих полях.
Запросы с низкими фильтрами избирательности (т.е. запросы, которые требуют больше, чем 10%
данных из таблиц, которые они используют) будут полезны MERGE JOINS
и HASH JOINS
.
Но для запросов, подобных приведенным выше, требуется NESTED LOOPS
работать эффективно.
Если вы разместите свои запросы и определения таблиц здесь, возможно, многое может быть сделано в отношении производительности индексов и запросов.
Ответ 2
Перед принятием таких решительных мер необходимо рассмотреть несколько вещей:
-
обновите свою установку до последней версии 8.2.x(сейчас это 8.2.12). Еще лучше - подумайте о переходе на следующую стабильную версию, которая составляет 8.3 (8.3.6).
-
рассмотрите возможность изменения вашей производственной платформы на нечто, отличное от Windows. Порт Windows PostgreSQL, хотя и очень полезный для целей разработки, по-прежнему не соответствует параметрам Un * x.
-
прочитайте первый абзац "" Настройка параметров планировщика ". Эта страница wiki page тоже поможет.
Ответ 3
У меня такой же опыт. Некоторые запросы в большой базе данных выполнялись с использованием вложенных циклов, и это заняло 12 часов!!! когда он запускается через 30 секунд при отключении вложенных циклов или удалении индексов.
Здесь были бы очень интересные подсказки, но я пробовал
...
SET ENABLE_NESTLOOP TO FALSE;
... critical query
SET ENABLE_NESTLOOP TO TRUE;
...
для решения этого вопроса. Таким образом, вы можете определенно отключить и снова включить использование вложенного цикла, и вы не можете спорить с увеличением в 9000 раз:)
Одна из проблем заключается в том, чтобы изменить ENABLE_NESTLOOP в процедуре PgSQL/PL. Я могу запустить SQL script в Aqua Data Studio, делая все правильно, но когда я помещаю его в процедуру PgSQL/PL, он все равно занимает 12 часов. По-видимому, он игнорировал изменения.