按原因排序

时间:2010-12-03 13:58:00

标签: mysql datetime innodb filesort

我仍有以下问题

EXPLAIN EXTENDED SELECT
  `item`.`id`,
  `item`.`timestamp`,
  `item`.`label`
  FROM
  item
WHERE
  item.dataTypeId=30
GROUP BY
  item.id
ORDER BY
  item.timestamp DESC
LIMIT 0,6;

Id&时间戳是主键对(mediumint + datetime) dataTypeId 是外键(mediumint) 表格创建为 InnoDb

可以有更多具有相同ID和不同时间戳(同一项目的版本)的记录。这是分组原因。

我读过这样的例子:similar topic on stackoverflow

但它没有解决我的问题。

我尝试创建以下索引:

  1. 索引(dataTypeId,id,timestamp) - 按此顺序
  2. 索引(dataTypeId,timestamp) - 按此顺序
  3. id
  4. 的索引
  5. 时间戳索引
  6. 最后两个是绝望的一小部分

    我想我必须错过一些基本的东西 -
    但真的不知道是什么 不要指望解决方案(这会很好:)只是踢我正确的方式:)

    sort_buffer_size现在是4194288

    修改 解释 - 没有索引

    "1" "SIMPLE"    "item"  "ref"   "FK_dataTypeId" "FK_dataTypeId" "4" "const" "5608"  "Using where; Using temporary; Using filesort"
    

    解释创建的索引

    "1" "SIMPLE"    "item"  "ref"   "FK_udssDataItem_1,testIndexType,testIndexTypeTimestamp,testIndexTypeIdTime"    "FK_udssDataItem_1" "4" "const" "5632"  "Using where; Using temporary; Using filesort"
    

2 个答案:

答案 0 :(得分:1)

所以你的问题是"如何避免查询中的文件输出" ?
在这种情况下,要让MySQL进行索引排序,您需要在where子句中包含索引中的所有列。

使用id,timestamp主键

where id = myid and item.timestamp between (t1,t2)

还要注意开放式范围(以及时间戳< now())

我不确定datatypeID是什么,但如果这是你唯一的条件,那么在该列上添加索引也应该建议索引排序。但您可能必须按顺序在(timestamp,datatypeID)...上创建索引...而不是。

答案 1 :(得分:1)

您的查询存在问题。当您执行“按ID分组”时,您可能具有相同ID的不同时间戳,并且未指定使用哪个(Min(),max()等)“label”字段会出现类似问题。

http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

所以你需要在时间戳和标签上使用agregate函数,否则返回的值可能是不可预测的。

由于您按ID进行分组并按时间戳排序,因此MySQL每组提取一个时间戳,因此索引实际上没有多大帮助。您可能无法使用此查询删除文件排序。