【问题标题】:how to index when querying range of values mysql如何在查询值范围mysql时建立索引
【发布时间】:2013-01-10 11:08:27
【问题描述】:

我有一个 sql 查询

 SELECT level, data, string, soln, uid 
 FROM user_data 
 WHERE level = 10 AND (timetaken >= 151 AND timetaken <= 217) AND uid != 1
 LIMIT 8852, 1;

从包含 150 万个条目的表中获取。

我已使用索引

alter table user_data add index a_idx (level, timetaken, uid); 

所以我面临的问题是在某些情况下查询需要超过 30 秒,在某些情况下不到 0.01 秒。

这里的索引有什么问题吗。

编辑: 添加解释查询详情

+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+
| id | select_type | table            | type  | possible_keys | key        | key_len | ref  | rows  | Extra                    |
+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | user_data | range | a_idx    | a_idx | 30      | NULL | 24091 | Using where; Using index |
+----+-------------+------------------+-------+---------------+------------+---------+------+-------+--------------------------+

表格中的数据字段是一个文本字段。在大多数情况下,它的长度大于 255 个字符。这会导致问题吗?

【问题讨论】:

    标签: mysql indexing


    【解决方案1】:

    首先,您应该尝试使用 EXPLAIN 获取此查询的执行计划:

     EXPLAIN SELECT level, data, string, soln, uid 
     FROM user_data 
     WHERE level = 10 AND (timetaken >= 151 AND timetaken <= 217) AND uid != 1
     LIMIT 8852, 1;
    

    这是一张很棒的幻灯片,可用于讨论该主题: http://www.slideshare.net/phpcodemonkey/mysql-explain-explained

    尝试添加不同的索引:

    • 一个关于 uid 和级别的
    • 一个单独的时间

    【讨论】:

      【解决方案2】:

      问题在于高偏移。为了选择第 8853 个结果,MySQL 必须扫描此之前的所有 8852 行。

      顺便说一句,使用没有 order by 的 limit 可能会导致意想不到的结果。

      为了加快高偏移量的查询,您应该使用 since..until 分页策略

      【讨论】:

      • 你所说的分页策略是什么意思@Darhazer
      猜你喜欢
      • 2018-05-24
      • 2017-03-05
      • 1970-01-01
      • 2012-10-14
      • 2018-07-31
      • 1970-01-01
      • 2011-08-21
      • 2021-01-19
      • 2018-11-20
      相关资源
      最近更新 更多