Выполняю практику по курсу подготовки к эксперту, суть задачи: прогнать тест, собрать ТЖ, написать скрипт, который покажет наиболее неоптимальные операции, и исправить их.
Попался один запрос, целиком выполняется долго, секунд 8, не дело конечно. Но суть не в том, что он выполняется медленно, а почему он выполняется медленно. Взглянув на текст запроса, видно, что есть соединение со срезом последних регистра сведений. Текст запроса не привожу, т.к он тут не особо важен. Потенциальное соединение с подзапросом, а в случае с postgres это ой как не хорошо. Ладно, берем и переписываем на программный срез, и тут я увидел то, что совсем не ожидал увидеть. Привожу кусок запроса (см. срин). Запрос примитивный, а вот план запроса нет.
Казалось бы, берем временную таблицу, соединяем ее с таблицей регистра, и ожидаем, что будет nested loops, где в качестве верхней таблицы будет временная таблица (в ней не много записей), а в качестве нижней - таблица регистра. У таблицы регистра есть подходящий индекс.
НО postgres упорно делает seq scan по всей таблице (где, к слову, 25 млн. записей), по условию периода, и потом hash join с временной таблицей.
Дай думаю прогоню тот же запрос, но уже на MS SQL. И ура, на MS я увидел тот план запроса, который ожидал увидеть на postgres. План запроса вполне уместный (скрин).
В итоге удалось заставить postgres выбрать нужный план, только соединив таблицу регистра напрямую с табличной частью документа. Тогда стал использоваться nested loops.
Вывод: угадать какой будет план запроса не так-то просто, поэтому единственный правильный вариант - посмотреть его актуальный план любым «удобным» способом.
>>Click here to continue<<