«id =» main «> Поделиться

CTE, или общие табличные выражения, также называемые конструкцией WITH, — это одна из конструкций SQL, которая предлагает альтернативный способ написания запроса, состоящего из подзапросов.

Для большинства механизмов и подзапросов баз данных CTE являются полностью эквивалентными конструкциями, каждый подзапрос можно переписать в CTE и наоборот. Затем (при условии, что он переписан правильно): он не только вернет идентичные результаты, но также может быть преобразован планировщик к идентичной форме. Поэтому они являются прекрасным примером так называемой синтаксической обледенения.

Стоит знать, что, в отличие от других систем баз данных, Postgres CTE не является синтаксической обледенением. Так что, если вы до сих пор работали с другими базами данных, то, что происходит в движке Postgres, может стать для вас сюрпризом. А именно, при оптимизации запроса вы можете внезапно заметить, что:

система начинает создавать временные файлы (зависит от настройки work_mem), вместо выборочного выбора нескольких строк с индексом появляется узел последовательного сканирования, т.е. последовательное чтение всей таблицы.

Следующие два запроса полностью отличаются от Postgres:

SELECT * FROM (SELECT n i_name, n i_price FROM generate_series (1, 10000) n) AS price_list WHERE i_price МЕЖДУ 10 И 100;

i

WITH price_list AS (SELECT n i_name, n i_price FROM generate_series (1, 10000) n) SELECT * FROM price_list WHERE i_price МЕЖДУ 10 И 100;

Конечно, возвращаемые ими данные будут идентичны, разница заключается в способ их обработки. В то время как при первом построении подзапрос может:

быть «сведен» к основному запросу и рассматриваться как одна инструкция, или подзапрос может быть материализован, и основной запрос будет обрабатывать ранее материализованные результаты или вывод подзапроса может быть перенаправлен родительскому элементу

, тогда в случае конструкций с WITH мы всегда наблюдаем материализацию. По этой причине CTE в postgres считается своего рода «подсказкой», аналогичной & nbsp;/* + материализации * в oracl. /, а точнее обходной путь, который позволяет использовать подсказки, не имея их :).

Rate this post