Modificación a GEQO (optimización de consulta genética) de PostgreSQL

16

Necesito implementar una funcionalidad que esté en línea con la funcionalidad GEQO de PostgreSQL. Entiendo que el enfoque de GEQO es codificar los planes de consulta como cadenas enteras y GEQO genera estas posibles secuencias de unión al azar. Fuente: http://www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

Mi pregunta: cómo modificar la función GEQO si conozco definitivamente la secuencia de unión correcta, para no tener que buscar diferentes secuencias de unión. Por ejemplo, si supiera que la mejor manera de unir las 4 relaciones es 4-1-3-2, no necesitaría verificar otras permutaciones.

No hay buenos materiales sobre cómo se implementa GEQO en PostgreSQL. PostgreSQL solo ofrece una vista general de la funcionalidad GEQO pero no explica mucho.

¿O podría lograr esta funcionalidad en standard_join_search () sin usar GEQO?

usuario2761431
fuente
3
Parece que quiere implementar sugerencias de consulta. Eso está muy bien, pero no debe esperar que se acepte el cambio en el núcleo de PostgreSQL porque la comunidad del proyecto no es lo que llamaría un gran fanático de las sugerencias de consulta. Si habla en serio sobre esto, necesitará leer un poco del código del planificador de consultas y deberá descubrir cómo pasar sus sugerencias desde el analizador hacia abajo a través de la reescritura y al planificador. No veo una respuesta rápida y simple aquí. Lo que finalmente desea hacer es forzar una elección de ruta particular en el planificador / optimizador.
Craig Ringer
Ah, sí, son escépticos sobre las sugerencias de consulta. He leído el código del planificador y parecía que GEQO sería una forma de minimizar los cambios en el núcleo existente.
user2761431
2
¿Es eso lo que está tratando de lograr, implementar sugerencias de consulta para forzar el orden de unión? Si es así, verifique si alguien más ya lo ha implementado. También debe considerar por qué lo necesita, por qué el planificador está tomando las decisiones equivocadas en primer lugar. Considere producir un caso de prueba autónomo e informar a pgsql-performance.
Craig Ringer
3
Hay pg_hint_plan : en.sourceforge.jp/projects/pghintplan , pero no lo utilicé . Una dba me dijo que estaba trabajando en 9.2. También hay un artículo en ruso al respecto habrahabr.ru/post/169751
ckorzhik

Respuestas:

1

Una forma de hacerlo sin la necesidad de perder el tiempo con GEKO es mediante el uso de CTE.

Los CTE son barreras de optimización, por lo tanto, podría envolver las uniones dentro de los CTE en el orden que desee y PG se verá obligado a hacerlo.

Por ejemplo, si queremos forzar al DB a unir primero t1 con t2 y solo entonces con t4 podríamos ejecutar algo como:

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;

Esto resultará en:

                                  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)

Este es solo un ejemplo, puede cambiarlo según sea necesario; en cualquier caso, PG no puede cambiar el orden entre los diferentes CTE.

Espero eso ayude :)

Cohenjo
fuente