mysql在大表上使用不正确的索引
问题 我有一个大约有200万行(115MB)的表,它将要大得多。在表上运行一些实用程序脚本时,我注意到我的一个查询花费了很长的时间(15秒以上),而之前几乎相同的查询只花费了不到半秒的时间。以下是查询: 问题1:mysql在大表上使用不正确的索引,mysql,Mysql,问题 我有一个大约有200万行(115MB)的表,它将要大得多。在表上运行一些实用程序脚本时,我注意到我的一个查询花费了很长的时间(15秒以上),而之前几乎相同的查询只花费了不到半秒的时间。以下是查询: 问题1: SELECT `id` FROM `my_table` WHERE `my_column`='test' ORDER BY `id` LIMIT 28000, 1000 Execution time: 0.204 seconds 问题2: SELECT `id` FROM `my_t
SELECT `id` FROM `my_table` WHERE `my_column`='test' ORDER BY `id` LIMIT 28000, 1000
Execution time: 0.204 seconds
问题2:
SELECT `id` FROM `my_table` WHERE `my_column`='test' ORDER BY `id` LIMIT 29000, 1000
Execution time: 10.203 seconds
索引和表信息
id
是主键,my_列
也被索引(尽管目前它的基数仅为1)
•id是一个整数•我的_列是一个varchar(50)
解释的查询 查询1:类型:索引,可能的键:我的列,键:主,键:4,行:29000,额外:使用where 查询2:键入:范围,可能的键:我的键列,键:我的键列,键列:53,行:2139123额外:使用where;使用文件排序 如您所见,第二个查询使用的是
my_列
键和文件排序,并将其永久化,但我所做的只是将限制偏移量增加1000。
我是如何临时解决问题的 1) 如果我删除
WHERE my_column='test'
条件,mysql优化器将正确使用主键进行排序,但我无法删除此条件,因为很快就会在my_column
中出现其他值,我需要为该查询过滤掉这些值
2) 如果我使用FORCE INDEX(PRIMARY)
mysql优化器也会使用适当的索引,但这似乎是一种攻击。
我的问题
为什么mysql选择使用
my_列
索引而不是主键?在表定义、索引或我的查询结构中有没有更好的方法来处理这个问题?我会尝试在(my_column,id)
的组合上创建一个。你试过添加一个综合指数吗
ALTER TABLE `my_table` ADD INDEX (id, my_column);
如果您只选择id,并且始终只在where子句中使用my_列,那么这应该可以正常工作。对于当前设置,有两种明显的方法来执行查询
id
顺序检索行,并丢弃与WHERE
子句不匹配的行WHERE
子句匹配的行,并按id
顺序对其排序my\u列
和id
上创建索引,MySQL可以从my\u列,id
的第一行开始,按顺序检索行
请注意,在一般情况下,这要求
WHERE
子句中的所有条件都相等,并且WHERE
子句中的所有列都存在于索引中。唉……我就是喜欢这样。感谢您的帮助您希望my_column
成为复合索引最左边的列,因为它是在WHERE子句中测试的列。