Mysql排序FileSort的问题

需求:

  有这样一张表(数据有5KW左右),我需要按照时间过滤出一部分数据,然后将这部分数据分页获取;

  id 主键

  create_date  时间戳  (二级索引)

  还有其他几十个字段

问题描述:

  我写的SQL大致如下:

  SELECT 很多个字段  FROM 表 WHERE create_date <= '2019-05-06' AND create_date >= '2019-05-05'  ORDER BY id LIMIT C, S;

  create_date 时间过滤,出来的数据大概有40W左右;

  Explain 看了一下,会扫描的数据大概在80W左右,还算比较合理;也会走到索引(个人第一直觉就是能用到的两个字段都有索引,不会有撒问题);就上线了;

  上线后发现这个语句要执行上千S,顿时就头大了;

问题原因:

  只有将SQL再explain一下,看看语句执行的解析过程;发现跟之前看的没撒差别,但是这次我发现最后EXTRA 信息中有个 filesort;之前应该也有,我忽略了;  

  大致找到问题所在了,使用了内存或磁盘排序,导致数据处理缓慢;

  但是这个和我潜意识的想法有点差别,两个列都有索引,为什么会出来filesort呢;

  再一看语句执行过程:

    1、先通过一个二级索引(create_date)筛选出需要的数据,这个没问题;

    2、将筛选出的数据排序,不是有主键索引么?在这难道就走不上了?

  第二步过程实际是:

    1、通过第一步二级索引得到的主键列表

    2、回表查询出筛选出记录的详细信息(这些信息在聚簇索引的叶子节点上)

    3、将筛选出的数据排序(filesort)

 

解决办法:

  不使用主键排序,使用查询条件 create_date字段来排序;

  这样执行过程大概是:

    1、根据create_date(索引)范围查询出合适记录;

    2、根据排序方向,过滤出真正需要的数据(这还是二级索引数据集合)

    3、回表查询步骤2索引列表的详细信息,并返回;

结论:

  WHERE 子句使用的索引,没有在排序中使用到,就会出现filesort;

 

posted @ 2019-06-27 16:13  lion_eagle  阅读(1167)  评论(2编辑  收藏  举报