使用 OR 语句时 Postgres SQL 很慢

Posted

技术标签:

【中文标题】使用 OR 语句时 Postgres SQL 很慢【英文标题】:Postgres SQL slow when using OR statement 【发布时间】:2019-05-10 01:32:10 【问题描述】:

我有一个需要 12 秒的查询(日志表 1.2m 行),根本原因如下

select 1
from
   myTable myTable
   join myJournal Journal on (Journal.status=0 and myTable.id = Journal.myTableId)
   join arrival Arrival on (myTable.id = Arrival.myTableId)
   join calc Calc on (myTable.id = Calculated.myTableId)
   join ms ms on (Parent.id = ms.myTableId)   
   join perf Perf on (myTable.id = Perf.myTableId)
   join ref Ref on (myTable.id = Ref.myTableId)
where
    ((myTable.name like 'cheese%' or 
     Journal.algorithm like 'cheese%' or --if this is removed, its fine <1sec
     myTable.client like 'cheese%' or 
     myTable.something like 'cheese%'))

但是日志表执行正常。在做

select * from myJournal where algorithm like 'cheese%' --takes < 1 sec.

如果我删除了四个连接(未在 where 子句中使用),查询也可以正常执行。

当我加入超过 3 个表时,性能会急剧/成倍下降。

【问题讨论】:

也许您可能需要在Journal(myTableId,status) 上建立一个复合索引。 据我所知,表达式ilike '%cheese%' 不能使用索引。如果您有这种需求,请考虑使用全文搜索。否则,如果要使用索引,请确保使用整个列或仅使用前缀,而不是后缀。 @TimBiegeleisen 好的,谢谢,但这并不能完全解释缓慢吗?因为该查询本身很快 嗯,您正在添加更多限制,这意味着需要更长的时间。在这里要清楚,您的“OK”查询可能没有使用索引。 @TimBiegeleisen 是的,我明白这一点。我已经编辑了我的问题,问题仍然存在 【参考方案1】:

我将首先将查询编写为:

select 1
from myTable t join
     myJournal j
     on t.id = j.myTableId
where j.status = 0 and
      (t.name like 'cheese%' or 
       j.algorithm like 'cheese%' or 
       t.client like 'cheese%' or 
       t.something like 'cheese%'
      )

那么最佳索引可能是myJournal(status, myTableId, algorithm)myTable(id, name, client, something)

这些索引主要用于join 和第一个过滤条件。它们对字符串比较没有多大帮助。但是,由于or 条件,这些很难优化。

【讨论】:

所以我认为我的问题是所有相关信息,但还有其他未在 where 中使用的连接。当我删除其他连接,但保留慢位 int 问题时,性能显着提高,与删除那个或语句一样多。我是否达到了加入的一些 postgres 门槛? 大声笑,我没有投反对票。事实证明,如果我加入超过 3 个表,性能会急剧下降。也许我正在达到一些 postgres 内部限制/阈值 @NimChimpsky 。 . .首先,您不能真正优化字符串上的OR 比较; OR 和字符串都会阻碍这一点(除非 Postgres 对此有奇特的机制)。其次,您可以优化JOINs。第三,在查看结果以衡量持续时间时,您必须小心。这可能与返回第一个结果的速度有关,而不是与所有结果有关。 仅供参考 SET LOCAL enable_nestloop = off;解决问题 @NimChimpsky 。 . .有趣的。复杂的where 子句导致 Postgres 切换到嵌套循环连接。对我来说,这听起来像是优化器中的一个错误。

以上是关于使用 OR 语句时 Postgres SQL 很慢的主要内容,如果未能解决你的问题,请参考以下文章

SQL 语句执行感觉很慢,怎么回事

SQL 语句执行很慢是怎么回事?

使用触发器将 postgres SQL 插入语句拆分为 2 个表

同事问我,SQL 语句明明命中了索引,为什么执行很慢?

sqlserver2000,为啥执行时很慢?仅仅是300条数据。求大神帮助

mysql做查询时,第一次很慢,第二三次就会很快?