【问题标题】:mySQL index parameters and limitsmySQL 索引参数和限制
【发布时间】:2018-07-13 01:21:08
【问题描述】:

我正在尝试找出 mySQL 中关于索引的设置。 mySQL 什么时候忽略索引?

这是一个实验的结果。我有一个在 AGE 列上有索引的表,如下所示。

CREATE TABLE `USERS` (
  `ID` int(11) NOT NULL,
  `FIRSTNAME` varchar(45) NOT NULL,
  `LASTNAME` varchar(45) DEFAULT NULL,
  `USERNAME` varchar(45) DEFAULT NULL,
  `ROLE` int(11) DEFAULT NULL,
  `PASSWORD` varchar(45) DEFAULT NULL,
  `AGE` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `USERS`
  ADD PRIMARY KEY (`ID`),
  ADD KEY `AGE` (`AGE`);

EXPLAIN 查询的结果。前三个语句使用索引。第二组语句忽略索引并进行全表扫描。

AGE 的范围是 20 到 100 年之间的随机值。表中有 1000 行。

/* utilizes the index on AGE */
/* case 1 */
SELECT ID, AGE  FROM USERS WHERE AGE > 20; 

/* case 2 */
SELECT AGE  FROM USERS WHERE AGE > 44;

/* case 3 */
SELECT * FROM USERS WHERE AGE > 84;


/* does not use index on AGE */

/* case 4 */
SELECT AGE, FIRSTNAME FROM USERS WHERE AGE > 83;

/* case 5 */
SELECT * FROM USERS WHERE AGE > 83;

/* case 6 */
SELECT AGE FROM USERS WHERE AGE > 18;

我看到的一些观察结果。谁能证实我的结论是正确的?

1) SELECT * 将在选择 15% 或更少的行时使用索引。 2) SELECT AGE 将在选择 1 行或更多行时使用索引。

【问题讨论】:

  • 使用格式化工具使您的帖子更具可读性。使用code blocking 表示代码、日志和错误文本,使用 bolditalics 突出显示内容
  • 我认为这些都是针对同一张表进行测试的。案例 3 和案例 5 尤其令人费解。可能在禁用缓存的情况下重新测试(即 `SELECT SQL_NO_CACHE )。

标签: mysql database select indexing


【解决方案1】:

15% 通常在 20% 左右,这取决于从表中的数据中收集的统计数据。我看到有人在他的查询中确定了大约 29% 的截止值。你实际上达到了 20%:

(100-85+1)/(100-20+1) = 19.8%
(100-84+1)/(100-20+1) = 21.0%

所以,这解释了案例 3​​、4、5。基本原理是,对于高百分比,表扫描比在索引 BTree 和数据+PK BTree 之间跳转更有效。

索引是“覆盖”这两个。也就是说,所有 必要的列都在单个索引中找到。因此,它应该使用索引,而不是进行表扫描:

SELECT AGE ...
SELECT ID, AGE ...

注意:在 InnoDB 中,二级索引隐式包含 PRIMARY KEY。也就是说,INDEX(age)INDEX(age, id) 几乎相同。

这解释了案例 1 和 2,但未能解释案例 6。案例 6 应该使用索引来返回整个 AGE 列表。 (不是 0 行,正如您的评论所说的那样??)

您的测试只是冰山一角,但在尝试了解 MySQL 相对简单的优化器的深度方面,您已经比大多数初学者走得更远了。 (我比你领先几年。)​​

还有一些经验法则here

请继续试验并发布您的结果。

【讨论】:

  • 很好的回应,但我不清楚你的第一句话是如何解释 3(使用过的索引)和 5(没有)的。你能详细说明一下吗?
  • @JoshuaR。 - 案例 3 需要接触的索引行较少,因此来回被认为成本不会太高。案例 5 有更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
相关资源
最近更新 更多