出奇地慢 Mysql 查询 OR

Weirdly slow Mysql Query on OR

我有以下需要 3 秒的查询

SELECT  SQL_NO_CACHE e.Id
    FROM  `Email` e
    LEFT JOIN  basedb.emailconnections ec  ON ec.id = e.EmailConnectionId
    LEFT JOIN  historydb.`event` ev  ON ev.EmailId = e.Id
    Where  e.UserId = 228
      OR  ev.PartnerId = 150
      AND  ev.Private = 0;

问题来自(e.UserId = 228 OR ev.PartnerId = 150 AND ev.Private = 0)

如果我运行像这样只从WHERE的左边部分,需要0.04秒

SELECT  SQL_NO_CACHE e.Id
    FROM  `Email` e
    LEFT JOIN  basedb.emailconnections ec  ON ec.id = e.EmailConnectionId
    LEFT JOIN  historydb.`event` ev  ON ev.EmailId = e.Id
    Where  e.UserId = 228;

如果我运行像这样正确的部分,需要0.03秒

SELECT  SQL_NO_CACHE e.Id
    FROM  `Email` e
    LEFT JOIN  basedb.emailconnections ec  ON ec.id = e.EmailConnectionId
    LEFT JOIN  historydb.`event` ev  ON ev.EmailId = e.Id
    Where  ev.PartnerId = 150
      AND  ev.Private = 0;

所以如果我 运行 2 个查询代替 运行 单个查询并且两个更快一次的结果计数匹配慢速一次

SQL_NO_CACHE仅用于调试

  • AND 通常比 OR.

  • 首先使用一个 table 的测试,然后它会“加入”另一个 table 并根据它进行过滤。这限制了 JOINWHERE.

    的效率
  • 检查这个;

    Where  e.UserId = 228
      OR  ev.PartnerId = 150
      AND  ev.Private = 0;
    

相同
Where  e.UserId = 228
   OR  ( ev.PartnerId = 150  AND  ev.Private = 0 );

如果这不是您想要的,请更改括号。

  • 这些索引可能有助于第一个查询(AND/OR 括在括号中):

    e:  INDEX(UserId, EmailConnectionId,  Id)
    ev:  INDEX(EmailId)
    
  • 如评论中所述,UNION通常是加速OR的方法。