哪些字段应该一起索引?通过...分组?订购?
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】:所有内容(field1
、is_current
、event_id
、pub_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,所以我会试试这个。以上是关于哪些字段应该一起索引?通过...分组?订购?的主要内容,如果未能解决你的问题,请参考以下文章