【问题标题】:MySql Explain ignoring the unique index in a particular queryMySql Explain 忽略特定查询中的唯一索引
【发布时间】:2012-12-11 13:53:18
【问题描述】:

我第一次开始深入研究索引,并第一次从用户表开始分析我们的数据库。我搜索了 SO 以找到一个类似的问题,但我猜无法很好地构建我的搜索。

我正在经历一个特定的概念,第一次观察让我想知道 - 这些解释的区别[区别:第一个查询使用 'a%',而第二个查询使用 'ab%']

[users 表中的总行数 = 9193]:

1) explain select * from users where email_address like 'a%';

(实际匹配的列 = 1240

2) explain select * from users where email_address like 'ab%';

(实际匹配的列 = 109

索引如下所示:

我的问题: 为什么在第一个查询中完全忽略索引? mySql 是否认为不使用case 1 中的索引更好?如果是,为什么?

【问题讨论】:

  • 问题中提到了一些有趣的点。但是,i)如答案之一中所述,30% 规则无效。 ii) 默认dev.mysql.com/doc/refman/5.0/en/… 显然非常高(我没有更改数据库中的任何默认值)。这个问题中提到的观点绝对是正确的方向。我仍在寻找确切的原因。也许我应该更多地谷歌。
  • 如果 30% 规则实际上是一个取决于表格大小的滑动比例,我不会感到惊讶。一张只有 9K 行的表,不是很大,使用索引可能节省不了多少。

标签: mysql select indexing explain


【解决方案1】:

如果基于 mysql 收集的关于值分布的统计信息的概率高于总行数的某个比例(通常为总行数的 1/11),mysql 认为简单地扫描整个表以读取磁盘更有效按顺序排列页面,而不是使用索引以随机顺序在磁盘页面周围跳转。

你可以试试这个查询,它可能使用索引:

where email_address between 'a' and 'az'

虽然进行全盘扫描实际上可能更快。

【讨论】:

  • 有道理。而且它没有选择索引。
【解决方案2】:

这不是对您问题的直接回答,但我仍然想指出(以防您已经不知道):

试试:

explain select email_address from users where email_address like 'a%';
explain select email_address from users where email_address like 'ab%';

MySQL 现在将在上述两个查询中使用索引,因为感兴趣的列可以直接从索引中获得。

可能在您执行“选择 *”的情况下,索引访问成本更高,因为优化器必须遍历索引记录,找到行 ID,然后返回表以检索其他列值。

但在上面的查询中,您只执行“选择电子邮件地址”,优化器知道所需的所有信息都可以直接从索引中获得,因此无论 30% 规则如何,它都会使用索引。

各位高手,如有错误请指正。

【讨论】:

  • 好吧,它似乎没有从索引中挑选,并且由于一些“其他”优化(如解释中所示)而更喜欢扫描表。
  • 即使您在 SELECT 子句中仅选择 email_address ?尝试运行分析表用户;看看解释计划是否有任何变化。
  • 是的(请参阅上面的解释输出),是的,我做到了:) @Barmar 所说的指出了正确的方向。
猜你喜欢
  • 1970-01-01
  • 2012-12-29
  • 2021-12-21
  • 2013-08-17
  • 2016-06-15
  • 2011-05-05
  • 1970-01-01
  • 2012-08-06
  • 2010-10-31
相关资源
最近更新 更多