Postgresql避免使用连接嵌套循环

时间:2017-10-01 09:06:40

标签: postgresql

请尽可能帮助我提高查询效果。

我有以下查询

    select
        s."CustomerCode",
        s."MaterialCode",
        fw."Name",
        fw."ReverseName",
        s."Uc"
    from
        "Sales" s
    left join
        "FiscalWeeks" fw on s."SalesDate" between fw."StartedAt" and fw."EndedAt"

执行计划是

"Nested Loop Left Join  (cost=0.00..1439970.46 rows=8954562 width=40) (actual time=0.129..114889.581 rows=1492427 loops=1)"
"  Join Filter: ((s."SalesDate" >= fw."StartedAt") AND (s."SalesDate" <= fw."EndedAt"))"
"  Rows Removed by Join Filter: 79098631"
"  Buffers: shared hit=3818 read=10884"
"  ->  Seq Scan on "Sales" s  (cost=0.00..29625.27 rows=1492427 width=26) (actual time=0.098..1216.287 rows=1492427 loops=1)"
"        Buffers: shared hit=3817 read=10884"
"  ->  Materialize  (cost=0.00..1.81 rows=54 width=26) (actual time=0.001..0.034 rows=54 loops=1492427)"
"        Buffers: shared hit=1"
"        ->  Seq Scan on "FiscalWeeks" fw  (cost=0.00..1.54 rows=54 width=26) (actual time=0.006..0.044 rows=54 loops=1)"
"              Buffers: shared hit=1"
"Planning time: 0.291 ms"
"Execution time: 115840.838 ms"

我有以下索引

CREATE INDEX "Sales_SalesDate_idx" ON public."Sales" USING btree ("SalesDate");
ADD CONSTRAINT "FiscalWeekUnique" EXCLUDE USING gist (daterange("StartedAt", "EndedAt", '[]'::text) WITH &&);

Postgresql版本

"PostgreSQL 9.5.0, compiled by Visual C++ build 1800, 32-bit"

进行真空分析

我认为postgresql不明白Sales表中的每一行只存在表FiscalWeeks中的一行并使用嵌套循环。我怎么解释呢?

谢谢。

1 个答案:

答案 0 :(得分:0)

由于连接条件,查询必须使用嵌套循环连接。运算符<=>=不支持散列或合并连接。

也许您可以通过向"FiscalWeeks"添加索引来改进查询,以便可以避免顺序扫描,并且可以将连接条件下推到内部循环中:

CREATE INDEX ON "FiscalWeeks" ("StartedAt", "EndedAt");

与此无关,但如果您避免使用表格和列名称中的大写字母,那么您的生活会更好。