基于所选列

时间:2016-04-30 13:24:22

标签: postgresql

我试图了解PostgreSQL如何简化查询:假设我有2个表(“tb_thing”和“tb_thing_template”),其中每个表都指向一个模板,我运行这样的查询:

EXPLAIN SELECT
    tb_thing.id
FROM
    tb_thing,
    tb_thing_template
WHERE
    tb_thing_template.id = tb_thing.template_id
;

结果如下:

                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 Hash Join  (cost=34.75..64.47 rows=788 width=4)
   Hash Cond: (tb_thing.template_id = tb_thing_template.id)
   ->  Seq Scan on tb_thing  (cost=0.00..18.88 rows=788 width=8)
   ->  Hash  (cost=21.00..21.00 rows=1100 width=4)
         ->  Seq Scan on tb_thing_template  (cost=0.00..21.00 rows=1100 width=4)

即使我只是从“tb_thing”中选择一个字段而没有从“tb_thing_template”中选择任何字段,规划人员也会加入这两个表格。我希望计划者能够聪明地弄清楚它不需要实际加入“tb_thing_template”表,因为我没有从中选择任何东西。

为什么要进行加入呢?为什么在计划查询时不考虑列选择?

谢谢!

1 个答案:

答案 0 :(得分:1)

从语义上讲,您的查询和简单的SELECT tb_thing.id FROM tb_thing不一样。

例如,假设表tb_thing_template有4行,其id值相同,也是tb_thing.template_id。然后,您的查询结果将包含4行tb_thing.id。相反,如果tb_thing.template_id中不存在tb_thing_template.id,则不会输出该行。

仅当tb_thing_template.idPRIMARY KEY(如此唯一)且tb_thing.template_idFOREIGN KEY id时,每个PRIMARY KEY只有一行{{ 1}},所以1:1关系,两个查询在语义上都是相同的。即使是在PK-FK关系中更典型的1:N关系,也需要语义意义上的连接。但是计划者无法知道这种关系是否是1:1,所以你得到了加入。

但你不应该试图欺骗查询计划器;它很聪明,但不一定比你(可能)愚蠢聪明。