Mysql 查询未按预期使用键

问题描述 投票:0回答:1

鉴于下表,为什么我的 EXPLAIN 说它没有使用任何键(特别是

tag_pos_nr
键?

CREATE TABLE `my_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag` mediumtext DEFAULT '0',
  `name` mediumtext DEFAULT 'John Doe',
  `pos` mediumtext DEFAULT '0',
  `comment` mediumtext DEFAULT '',
  `nr` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `tag_pos_nr` (`tag`(20),`pos`(20),`nr`),
  KEY `tag` (`tag`(20))
EXPLAIN SELECT id from my_tbl WHERE tag LIKE '%191223%' AND pos='pos1' AND nr=1;
+------+-------------+---------+------+---------------+------+---------+------+-------+-------------+
| id   | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+------+-------------+---------+------+---------------+------+---------+------+-------+-------------+
|    1 | SIMPLE      | my_tbl  | ALL  | NULL          | NULL | NULL    | NULL | 14238 | Using where |
+------+-------------+---------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.000 sec)

mysql indexing query-optimization
1个回答
0
投票
  • 前缀(例如

    tag(20)
    )实际上毫无用处。我认为我从未见过两个前缀在复合索引中有用,如您的
    tag_pos_nr
    .

  • LIKE '%...'
    不能使用索引(“覆盖”除外;见下文)。

  • 使用 that

    WHERE tag LIKE '%191223%' AND pos='pos1' AND nr=1
    模式可以完成的最好的事情是

      INDEX(nr)
    

    或者也许

      INDEX(nr, pos(20))
    
  • WHERE
    中子句的顺序并不重要(优化器会根据需要重新排列它们);
    INDEX
    中的顺序很重要。

  • 如果标签、名称和/或 pos 从来都不是很大,请更改为

    VARCHAR(...)
    并删除
    INDEXes
    中的前缀。

  • 当您还有
  • INDEX(a)

    时,

    INDEX(a,b)
    就是多余的。

  • “覆盖”索引是包含查询中任何地方使用的所有列的索引。注意:前缀不允许“覆盖”,因为索引中缺少部分列。

© www.soinside.com 2019 - 2024. All rights reserved.