对 PostgreSQL 的 GEQO(遗传查询优化)的修改

use*_*431 16 postgresql optimization

我需要实现一个符合 PostgreSQL 的 GEQO 功能的功能。我知道 GEQO 方法是将查询计划编码为整数字符串,而 GEQO 会随机生成这些可能的连接序列。来源:http : //www.postgresql.org/docs/9.3/static/geqo-pg-intro.html

我的问题:如果我明确知道正确的连接序列,如何修改 GEQO 函数,这样我就不必搜索不同的连接序列。例如,如果我知道加入 4 个关系的最佳方式是 4-1-3-2,我就不必检查其他排列。

关于如何在 PostgreSQL 中实现 GEQO 没有任何好的材料。PostgreSQL 只给出了 GEQO 功能的整体视图,但并没有做太多解释。

或者我可以在不使用 GEQO 的情况下在 standard_join_search() 本身中实现这个功能吗?

小智 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;
Run Code Online (Sandbox Code Playgroud)

这将导致:

                                  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)
Run Code Online (Sandbox Code Playgroud)

这只是一个示例,您可以根据需要更改它 - 在任何情况下 PG 都无法更改不同 CTE 之间的顺序。

希望能帮助到你 :)