【问题标题】:SQL "OR" in the where clause causing no index to be usedwhere 子句中的 SQL“OR”导致不使用索引
【发布时间】:2011-10-26 17:09:28
【问题描述】:

我有一个查询如下:

SELECT COUNT(Table1.Identifier) AS NonCancelCnt 
FROM Table1, Table2 
LEFT JOIN eventattendees ON eventattendees.AttendeeID = 47322 
LEFT JOIN eventsignup ON eventattendees.AttendeeID = eventsignup.AttendeeID 
LEFT JOIN transactions on transactions.registrationID=eventsignup.regid 
WHERE ((eventsignup.EventID = Table1.Identifier) Or (eventsignup.EventID = Table1.AttendanceLinkID)) 

“OR”子句导致不使用索引。如果我删除任一部分,我的执行路径将从 95,000 变为 200,并且速度会大大提高。

我对返工这样的东西不是很有经验,我这样做的最佳选择是什么?

【问题讨论】:

  • 您可以将 OR 条件之一移动到“第二个”查询中,然后使用 UNION 将它们重新连接起来......优化器一开始就无法解决这个问题是不寻常的。
  • 可能值得一试。也许统计数据已经过时,并且规划者认为大多数行是 x 或 y,所以不费心点击索引?如果EventID IN (...) 会更好,我会徘徊吗?
  • 除了答案之外,Table1 和 Table2 的上下文是什么,它们的关系,以及你试图从这个查询中得到什么......你的整体 COUNT() 只是要给出一个数字没有任何事件或与会者的上下文。

标签: mysql


【解决方案1】:

首先,您应该重写查询以指定 Table1、Table2 和 eventattendees 是如何连接的。还要选择是要在 WHERE 子句中还是在 JOIN 关键字之后指定用于连接的列。稍微清理一下之后,优化器可能会更好地选择要使用的正确索引。

如果这仍然不起作用,您可以使用 SQL 提示来指定您希望优化器使用的索引:

WITH INDEX(IX_nameofindex)

【讨论】:

    【解决方案2】:
    SELECT COUNT(Table1.Identifier) AS NonCancelCnt 
    FROM Table1, Table2 
    LEFT JOIN eventattendees ON eventattendees.AttendeeID = 47322 
    LEFT JOIN eventsignup ON eventattendees.AttendeeID = eventsignup.AttendeeID 
    LEFT JOIN transactions on transactions.registrationID=eventsignup.regid 
    WHERE eventsignup.EventID = Table1.AttendanceLinkID
    
    union all
    
    SELECT COUNT(Table1.Identifier) AS NonCancelCnt 
    FROM Table1, Table2 
    LEFT JOIN eventattendees ON eventattendees.AttendeeID = 47322 
    LEFT JOIN eventsignup ON eventattendees.AttendeeID = eventsignup.AttendeeID 
    LEFT JOIN transactions on transactions.registrationID=eventsignup.regid 
    WHERE eventsignup.EventID = Table1.Identifier
    

    【讨论】:

      【解决方案3】:

      不了解 Table1 和 Table2 是什么,也不是以任何形状连接,你会得到笛卡尔结果(对于 Table1 中的每条记录,将与 Table2 中的每条记录连接)

      另外,你的 where 子句可以用 IN 子句来简化

      where
         eventsignup.EventID IN ( Table1.Identifier, Table1.AttendanceLinkID )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-05
        • 2020-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        相关资源
        最近更新 更多