PSQL:如何优化此查询的执行时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PSQL:如何优化此查询的执行时间相关的知识,希望对你有一定的参考价值。

我有以下查询:

SELECT "factures"."id" 
FROM   "factures" 
WHERE  ( "factures"."id" NOT IN (SELECT DISTINCT( "echeances"."facture_id" ) 
                                 FROM   "echeances" 
                                 WHERE  "echeances"."type_decheance" IN ( 2, 3, 4, 5, 8, 9 ) 
                                        AND "echeances"."facture_id" IS NOT NULL 
                                 LIMIT  100000)) <----- removing this limit makes the query take enormous time
ORDER  BY "factures"."id" DESC

这里是限制为100 000的解释分析:

Index Only Scan Backward using factures_id_pkey on factures  (cost=93516.76..211292.17 rows=530570 width=4) (actual time=1425.701..11466.759 rows=963698 loops=1)
  Filter: (NOT (hashed SubPlan 1))
  Rows Removed by Filter: 99997
  Heap Fetches: 1063695
  SubPlan 1
    ->  Limit  (cost=0.43..93266.34 rows=100000 width=4) (actual time=0.022..1229.925 rows=100000 loops=1)
          ->  Unique  (cost=0.43..264837.37 rows=283959 width=4) (actual time=0.022..1090.692 rows=100000 loops=1)
                ->  Index Scan using echeances__facture_id__idx on echeances  (cost=0.43..262883.29 rows=781631 width=4) (actual time=0.020..819.735 rows=100167 loops=1)
                      Index Cond: (facture_id IS NOT NULL)
"                      Filter: (type_decheance = ANY ('2,3,4,5,8,9'::integer[]))"
                      Rows Removed by Filter: 156995
Planning time: 0.249 ms
Execution time: 11960.423 ms

这里是无限制的说明:

->  Unique  (cost=0.43..264837.37 rows=283959 width=4)
Index Only Scan Backward using factures_id_pkey on factures  (cost=0.86..142233669403.15 rows=530570 width=4)
  Filter: (NOT (SubPlan 1))
  SubPlan 1
    ->  Materialize  (cost=0.43..267367.16 rows=283959 width=4)
                ->  Index Scan using echeances__facture_id__idx on echeances  (cost=0.43..262883.29 rows=781631 width=4)
                      Index Cond: (facture_id IS NOT NULL)
"                      Filter: (type_decheance = ANY ('2,3,4,5,8,9'::integer[]))"

这是架构

Table "factures"
id

Table "echeances"
id
facture_id (fk)
type_decheance (integer)

问题是,如果::“ factures”和“ echeances”表具有大量行,

  • 在子查询中指定了限制,例如限制为100000,查询时间很快

  • Limit在子查询中未指定,这需要很多时间,我不得不在等待15分钟以上后将其停止。

  • 目标是使此查询不受限制并在合理的时间内运行。

我有以下查询:从“ factures”中选择SELECT“ factures”。“ id”(“ factures”。“ id” NOT IN(从“ echeances”中选择DISTINCT(“ echeances”。“ facture_id”)...

答案

切换到NOT EXISTS

以上是关于PSQL:如何优化此查询的执行时间的主要内容,如果未能解决你的问题,请参考以下文章

执行多个查询时,“psql -c”和“psql -f”有啥区别?

如何优化此查询并使其执行得更快? [关闭]

优化在文本搜索中使用正则表达式的 psql 查询

为啥不能在多行执行 PSQL 元命令

如何减少此脚本的执行时间?

在 Windows 上的 R 中执行 PSQL