为什么即使表被编入索引,我的查询也会检查1000行?

时间:2016-10-06 17:50:16

标签: mysql

该表有大约20K行,以下是创建代码:

CREATE TABLE `inventory` (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `TID` int(11) DEFAULT NULL,
      `RID` int(11) DEFAULT NULL,
      `CID` int(11) DEFAULT NULL,
      `value` text COLLATE utf8_unicode_ci,
      PRIMARY KEY (`ID`),
      KEY `index_TID_CID_value` (`TID`,`CID`,`value`(25))
    );

这是解释查询的结果

mysql> explain select rowID from inventory where TID=4 and CID=28 and value=3290843588097;
+----+-------------+------------+------+------------------------+-----------------------+---------+-------------+------+-------------+
| id | select_type | table      | type | possible_keys          | key                   | key_len | ref         | rows | Extra       |
+----+-------------+------------+------+------------------------+-----------------------+---------+-------------+------+-------------+
|  1 | SIMPLE      | inventory  | ref  | index_TID_CID_value    | index_TID_CID_value   | 10      | const,const | 9181 | Using where |
+----+-------------+------------+------+------------------------+-----------------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)

TID = 4和CID = 28的组合在表格中有大约13K行。

我的问题是:

  1. 为什么解释结果告诉我大约9k行 检查以获得最终结果?

  2. 为什么列ref仅显示const,const,因为多列索引中包含3列不应该refconst,const,const

  3. 2016年10月7日更新

    查询:

    select rowID from inventory where TID=4 and CID=28 and value=3290843588097;
    

    我跑了大约10次并且花了最后五次的时间(它们是相同的)

    • 无索引 - 0.02秒
    • 索引(TID,CID) - 0.03秒
    • 索引(TID,CID,值) - 0.00秒

    同样的解释查询今天看起来不同,如何?? 注意密钥len已更改为88并且ref已更改为const,const,const也要检查的行已减少到2

    mysql> explain select rowID from inventory where TID=4 and CID=28 and value='3290843588097';
    +----+-------------+-----------+------+----------------------+---------------------+---------+-------------------+------+-------------+
    | id | select_type | table     | type | possible_keys        | key                 | key_len | ref               | rows | Extra       |
    +----+-------------+-----------+------+----------------------+---------------------+---------+-------------------+------+-------------+
    |  1 | SIMPLE      | inventory | ref  | index_TID_CID_value  | index_TID_CID_value | 88      | const,const,const |    2 | Using where |
    +----+-------------+-----------+------+----------------------+---------------------+---------+-------------------+------+-------------+
    1 row in set (0.04 sec)
    

1 个答案:

答案 0 :(得分:0)

明确回答您的问题。

  1. 由于引擎需要搜索索引树以查找与where子句条件匹配的行ID,因此解释计划为您提供了大约9k行查询。索引将生成索引列值的每个可能组合的映射到与该组合关联的rowID的列表。实际上,引擎正在搜索这些组合以找到正确的组合;这是通过扫描组合来完成的,因此约为9k。

  2. 由于where子句标准涉及所有三个索引列,因此引擎通过利用前两列的索引优化搜索,然后将第三列短路并获取所有rowID结果那个组合。

  3. 在您的特定用例中,我假设您希望优化搜索的效果。我建议你只在TID和CID上创建一个索引(而不是值)。这样做的原因是,您目前在~20k记录中只有2个这些值的组合。这意味着使用只有2列的索引,在对所有三个值进行搜索时,引擎几乎可以立即删除一半的记录。 (这都是假设此索引将应用于具有更大数据集的表。)由于您的度量标准基于较小的数据集,因此您可能无法看到使用索引之间的性能差异的数量级。