Модификация GEQO (Генетическая оптимизация запросов) PostgreSQL

16

Мне нужно реализовать функциональность, которая соответствует функциональности GEQO в PostgreSQL. Я понимаю, что подход GEQO заключается в кодировании планов запросов в виде целочисленных строк, и GEQO генерирует эти возможные последовательности соединения случайным образом. Источник: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Мой вопрос: как изменить функцию GEQO, если я точно знаю правильную последовательность соединений, чтобы мне не приходилось искать разные последовательности соединений. Например, если бы я знал, что лучший способ соединения 4 отношений - это 4-1-3-2, мне не нужно проверять другие перестановки.

Нет хороших материалов о том, как GEQO реализован в PostgreSQL. PostgreSQL только дает общее представление о функциональности GEQO, но мало что объясняет.

Или я мог бы достичь этой функциональности в самой standard_join_search () без использования GEQO?

user2761431
источник
3
Похоже, вы хотите реализовать подсказки запроса. Это все хорошо, но вы не должны ожидать, что изменения будут приняты в ядре PostgreSQL, потому что проектное сообщество - это не то, что вы бы назвали большим поклонником подсказок запросов. Если вы серьезно относитесь к этому, вам нужно будет прочитать довольно много кода планировщика запросов и выяснить, как передать свои подсказки от анализатора через переписывающее устройство в планировщик. Я не вижу быстрого и простого ответа здесь. В конечном итоге вы хотите навязать определенный путь в планировщике / оптимизаторе.
Крейг Рингер
Ах, да, они скептически относятся к подсказкам запросов. Я прочитал код планировщика, и казалось, что GEQO позволит минимизировать изменения в существующем ядре.
user2761431
2
Это то, что вы пытаетесь достичь, внедряя подсказки запросов для принудительного упорядочения соединений? Если это так, посмотрите, реализовал ли это кто-то еще. Вы также должны подумать, зачем вам это нужно, почему планировщик делает неправильный выбор. Рассмотрите возможность создания автономного тестового примера и создания отчетов для pgsql-performance.
Крейг Рингер,
3
Существует pg_hint_plan : en.sourceforge.jp/projects/pghintplan , но я им не пользовался. Один дба сказал мне, что работает на 9.2. Об этом также есть статья на русском языке habrahabr.ru/post/169751
ckorzhik

Ответы:

1

Один из способов сделать это без необходимости возиться с GEKO - использовать CTE.

CTE - это барьеры оптимизации, поэтому вы можете обернуть объединения внутри CTE в нужном вам порядке, и PG будет вынужден это сделать.

Например, если мы хотим заставить БД сначала присоединиться к t1 с t2 и только потом с t4, мы могли бы выполнить что-то вроде:

explain 
with j1 as (select *,t1.c4 as t1c4 from t1 join t2 on (t1.c2=t2.id))
    ,j2 as (select * from j1 join t4 on (t1c4=t4.id))
select * from j2;

Это приведет к:

                                  QUERY PLAN                                   
-------------------------------------------------------------------------------
CTE Scan on j2  (cost=51485.00..67785.00 rows=815000 width=64)
CTE j1
 ->  Hash Join  (cost=3473.00..14521.00 rows=815000 width=40)
       Hash Cond: (t2.id = t1.c2)
       ->  Seq Scan on t2  (cost=0.00..26.30 rows=1630 width=20)
       ->  Hash  (cost=1637.00..1637.00 rows=100000 width=20)
             ->  Seq Scan on t1  (cost=0.00..1637.00 rows=100000 width=20)
CTE j2
 ->  Hash Join  (cost=289.00..36964.00 rows=815000 width=64)
       Hash Cond: (j1.t1c4 = t4.id)
       ->  CTE Scan on j1  (cost=0.00..16300.00 rows=815000 width=44)
       ->  Hash  (cost=164.00..164.00 rows=10000 width=20)
             ->  Seq Scan on t4  (cost=0.00..164.00 rows=10000 width=20)
(13 rows)

Это всего лишь пример, вы можете изменить его по мере необходимости - в любом случае PG не может изменить порядок между различными CTE.

Надеюсь, это поможет :)

cohenjo
источник