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

时间:2012-02-08 21:40:40

标签: mysql

问题

我有一个大约200万行(115 MB)的表,而且它的数量要大得多。当在桌面上运行一些实用程序脚本时,我注意到我的一个查询花了很长时间(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_column也被编入索引(尽管目前其基数仅为1)

•id是一个int •my_column是varchar(50)

查询解释

查询1:输入:index, possible_keys :my_column,:PRIMARY, key_len :4, :29,000,额外:使用

查询2:输入:范围, possible_keys :my_column,:my_column, key_len: 53, :2,139,123 额外:使用where;使用filesort

正如您所看到的,第二个查询正在使用my_column键和filesort并且永远占用,但我所做的只是将限制偏移量增加1,000。

我如何暂时解决问题

1)如果我删除了WHERE my_column = 'test'条件,mysql优化器正确地使用主键进行排序,但我无法删除这个条件,因为很快就会在my_column中有其他值我需要过滤掉这个查询。

2)如果我使用FORCE INDEX (PRIMARY),mysql优化器也将使用正确的索引,但这似乎是一种黑客攻击。

我的问题

为什么mysql确实选择使用my_column索引而不是主键?是否有更好的方法可以在表定义,索引或我的查询结构中处理它?<​​/ p>

3 个答案:

答案 0 :(得分:3)

我会尝试在(my_column, id)

的组合上创建composite index

答案 1 :(得分:0)

这很奇怪。您是否尝试过添加综合索引?

ALTER TABLE `my_table` ADD INDEX  (id, my_column);

如果你只选择id并且总是只在where子句中使用my_column,这应该可以正常工作。

答案 2 :(得分:0)

使用当前设置,有两种显而易见的方法可以执行查询。

  1. id顺序检索行,并丢弃那些与WHERE子句不匹配的行。
  2. 检索与WHERE子句匹配的行,并按id顺序对其进行排序。
  3. 据推测,MySQL根据你想要的行数来猜测使用哪种方式。

    但是,如果您在my_columnid上创建索引,则MySQL可以按my_column, id顺序检索行,从my_column = 'test'的第一行开始。

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