MySQL索引参数和限制

时间:2018-07-13 01:21:09

标签: mysql database select indexing

我试图弄清索引中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查询的结果。前三个语句使用索引。第二组语句忽略索引并进行全表扫描。

年龄范围在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)选择1行或更多行时,SELECT AGE将使用索引。

1 个答案:

答案 0 :(得分:2)

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相对简单的Optimizer的深度。 (我已经好几年开始了。)

还有更多经验法则here

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