mysql在大表上使用不正确的索引

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

问题

我有一个大约有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_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
    顺序对其排序
  • 据推测,MySQL正在根据您需要的行数猜测使用哪种方式

    但是,如果在
    my\u列
    id
    上创建索引,MySQL可以从
    my\u列,id
    的第一行开始,按顺序检索行


    请注意,在一般情况下,这要求
    WHERE
    子句中的所有条件都相等,并且
    WHERE
    子句中的所有列都存在于索引中。

    唉……我就是喜欢这样。感谢您的帮助您希望
    my_column
    成为复合索引最左边的列,因为它是在WHERE子句中测试的列。