0

我有以下查询:

  SELECT dt_stamp
    FROM claim_notes
   WHERE type_id             = 0
     AND dt_stamp           >= :dt_stamp
     AND DATE( dt_stamp )    = :date
     AND user_id             = :user_id
     AND note             LIKE :click_to_call
   ORDER BY dt_stamp
   LIMIT 1

claim_notes表有大约一百万行,因此该查询运行非常缓慢,因为它必须搜索未索引的note列(我对此无能为力)。我知道,当应用type_iddt_stampuser_id条件时,我将搜索大约 60 行而不是 50 万行。但是 MySQL 似乎并没有按顺序应用这些。我想做的是看看是否有办法告诉 MySQL 只将note LIKE :click_to_call条件应用于满足前一个条件的行,这样它就不会搜索具有这个条件的所有行。

我想出的是:

  SELECT dt_stamp
    FROM (
            SELECT *
              FROM claim_notes
             WHERE type_id           = 0
               AND dt_stamp         >= :dt_stamp
               AND DATE( dt_stamp )  = :date
               AND user_id           = :user_id
         )
     AND note LIKE :click_to_call
   ORDER BY dt_stamp
   LIMIT 1

这很有效,而且速度非常快。我只是想知道这是否是正确的方法,或者是否有更官方的方法来处理它。

4

2 回答 2

0

不要选择派生表解决方案,因为它性能不佳。我很惊讶拥有=>=运营商 MySQL 是LIKE第一个。

无论如何,我想说你可以尝试在这些字段上添加一些索引,看看会发生什么:

ALTER TABLE claim_notes ADD INDEX(type_id, user_id);
ALTER TABLE claim_notes ADD INDEX(dt_stamp);

后一个索引实际上不会改进对索引的搜索,而是改进结果的排序。

当然,有一个EXPLAIN查询会有所帮助。

于 2013-10-06T20:27:38.907 回答
0

没有必要这样做。如果您的 WHERE 子句中有多个以 . 分隔的术语,MySQL 优化器可以处理它AND。基本上,它知道如何“应用所有可以使用索引的条件,然后将未索引的表达式应用到剩余的行”。

但是选择正确的索引很重要。AND多列索引比单个索引更适合一系列术语。MySQL 可以应用索引交集,但这远不如使用单个索引查找相同的行有效。

一些逻辑规则适用于创建多列索引:

  • 唯一列上的条件优先于非唯一列上的条件。

  • 等式条件 ( =) 优于范围 ( >=, IN, BETWEEN,!=等)。

  • 在用于范围条件的索引中的第一列之后,后续列将不使用索引。

  • 大多数时候,在列(例如DATE(dt_stamp))上搜索函数的结果不会使用索引。在这种情况下,最好存储DATE数据类型并使用=而不是>=.

  • 如果条件匹配> 20% 的表,MySQL 可能会决定跳过索引并进行表扫描。

以下是我和我在 Percona 的同事举办的一些网络研讨会,以帮助解释索引设计:

您可以免费获取这些网络研讨会的幻灯片,并免费查看录制内容,但录制内容需要注册。

于 2013-10-06T20:33:56.610 回答