哪些字段应该一起索引?通过...分组?订购?

Posted

技术标签:

【中文标题】哪些字段应该一起索引?通过...分组?订购?【英文标题】:What fields should be indexed together? group by? order by? 【发布时间】:2010-10-05 18:42:08 【问题描述】:

我正在尝试加快我目前的查询速度:

SELECT * 
FROM `events` 
WHERE (field1 = 'some string' or field1 = 'some string') 
    and is_current = true 
GROUP BY event_id 
ORDER BY pub_date

这大约需要 30 秒。

field1 是一个 varchar(150)

我目前正在编制索引 field1、is_current、event_id、pub_data 慈善,pub_date,is_current 以及所有字段单独...

我真的不确定应该一起索引哪些字段,当我删除 order by 时,查询速度最高可达 8 秒左右,如果我同时删除 order by 和 group by,则不到 1 秒。 ..

在这种情况下究竟应该对什么进行索引以加快查询速度?

编辑: 我已经对修改后的查询(不再包括分组依据)运行了解释:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
    1   SIMPLE  events  range   is_current,field1_2,field1_3,field1_4,field1    field1_3    153     NULL    204336  Using where; Using filesort

这表明它正在使用键 field1_3,即:field1 & is_current 虽然它没有使用包含这两个字段和 pub_date 的键(用于排序..?)

它也在使用 FILESORT,这似乎是主要问题..

任何想法为什么它使用文件排序,即使 pub_date 字段也被索引(与其他字段一起)?

【问题讨论】:

select * 和 group by 语句在单个语句中可能是主要问题。我建议使用完整的字段名而不是 * 【参考方案1】:

所有内容(field1is_currentevent_idpub_date)都在一个索引中。 mysql 在一个查询中每个连接表只能使用一个索引。

使用EXPLAIN 看看你这样做时会发生什么。

另外,顺便说一句 - 正如 KoolKabin 所说,* 很少是一个好主意。有时 MySQL 会复制临时表中的行;然后是沟通成本。你对它的要求越少,事情就会越快。

更新:其实我错了。对不起。首先,如果您的分组与您的排序不同,您将无法充分利用索引。其次,您是否有一个索引,其中您的排序键 (pub_date) 是第一个?如果没有,请尝试这是否解决了订购问题。

【讨论】:

我已将查询限制为仅选择我感兴趣的 5 个字段,并暂时删除了 group by,尽管返回结果仍需要 8-9 秒。还带有查询中使用的所有字段的相关索引。 嗯...您可以对其运行 EXPLAIN 并将其粘贴到问题中吗?也许会有一些线索...... 刚刚更新了问题的详细信息,似乎使用的索引不包括索引中的order by 字段? (即使存在) 我已经更新了这个以首先包含一个带有 pub_date 的索引,尽管它仍然使用以前的键和文件排序【参考方案2】:

任何想法为什么它使用文件排序,即使 pub_date 字段也被索引(与其他字段一起)?

这是因为 mysql 优化器正在尝试使用索引“field1”并且您希望数据按 pub_date 排序。如果您使用的是 mysql 5.1(以下查询在早期版本中会出错),您可以强制 mysql 使用 pub_date 索引进行排序,类似这样

SELECT * 
FROM `events` 
force index for order by (pub_date)
WHERE (field1 = 'some string' or field1 = 'some string') 
    and is_current = true 
GROUP BY event_id 
ORDER BY pub_date

【讨论】:

谢谢你,我目前正在运行 4.x,但服务器将在周末升级到 5.x,所以我会试试这个。

以上是关于哪些字段应该一起索引?通过...分组?订购?的主要内容,如果未能解决你的问题,请参考以下文章

使用group by with order一起查询时间慢

如何通过邮政编码订购?

Django:通过注释字段的总和订购查询集?

更改模型以添加“通过”关系以订购多对多字段 - Django 1.7 迁移修改

通过特定的自定义字段订购 WP 查询,不起作用

JPA 2:通过不在带有额外字段的多对多中工作来订购