为什么未使用的FROM表会使语句变慢

Fab*_*ndl 2 sql postgresql indexing

我有两张桌子.一个changelog-table,其详细信息在这里并不重要.另一个包含卖家信息的表格,最重要的是有两列:

  • 主要身份证件
  • 和一个名为ident(= realworld ID)的id.

更改卖家时,会创建一个新条目,ident保持不变,但新条目获取新ID.我有ID的主索引和(ident,-id)上的另一个索引,所以我可以快速获得当前数据.

有机会我发现以下奇怪的行为:

这需要花费很长时间才能完成:

SELECT DISTINCT ON (ident) sellers.* FROM changelog, sellers ORDER BY ident,id DESC;

                                  QUERY PLAN                                    
---------------------------------------------------------------------------------
 Unique  (cost=741675.98..760122.47 rows=10 width=30)
   ->  Sort  (cost=741675.98..750899.22 rows=3689298 width=30)
         Sort Key: sellers.ident, sellers.id
         ->  Nested Loop  (cost=3.07..74457.37 rows=3689298 width=30)
               ->  Seq Scan on changelog  (cost=0.00..668.34 rows=38034 width=0)
               ->  Materialize  (cost=3.07..4.04 rows=97 width=30)
                     ->  Seq Scan on sellers  (cost=0.00..2.97 rows=97 width=30)
Run Code Online (Sandbox Code Playgroud)

当我用-ID替换DESC时它很快,但产生相同的结果.

SELECT DISTINCT ON (ident) sellers.* FROM changelog, sellers ORDER BY ident,-id;

                                         QUERY PLAN                                        
------------------------------------------------------------------------------------------
 Unique  (cost=706.37..92956.53 rows=10 width=30)
   ->  Nested Loop  (cost=706.37..83733.28 rows=3689298 width=30)
         ->  Index Scan using idx_sellers on sellers  (cost=0.00..17.70 rows=97 width=30)
         ->  Materialize  (cost=706.37..1086.71 rows=38034 width=0)
               ->  Seq Scan on changelog  (cost=0.00..668.34 rows=38034 width=0)
Run Code Online (Sandbox Code Playgroud)

当我从FROM中移除"changelog"时,ORDER BY -id和DESC给出相同的查询计划,再次快速.

SELECT DISTINCT ON (ident) sellers.* FROM sellers ORDER BY ident,id, DESC   

                             QUERY PLAN                              
---------------------------------------------------------------------
 Unique  (cost=6.17..6.66 rows=10 width=30)
   ->  Sort  (cost=6.17..6.41 rows=97 width=30)
         Sort Key: ident, id
         ->  Seq Scan on sellers  (cost=0.00..2.97 rows=97 width=30)
Run Code Online (Sandbox Code Playgroud)

我的问题:

  • 为什么在FROM中包含一个未使用的表会影响查询?
  • 为什么ORDER BY ident,-id不使用与ORDER BY ident,id DESC相同的计划?

编辑:我的实际查询当然有一个WHERE子句来连接这两个表.

HLG*_*GEM 9

在查询中没有未使用的表.

SELECT DISTINCT ON (ident) sellers.* 
FROM changelog, sellers ORDER BY ident,id DESC
Run Code Online (Sandbox Code Playgroud)

您的原始查询正在创建交叉连接(更改日志中的每个记录都连接到卖家中的每个记录),这是您应该避免使用20年前用显式语法替换的隐含连接语法的一个原因.