索引是否依赖于所选列?

kan*_*rbk 4 mysql

我正在根据时间执行大多数查询.所以我为创建的时间创建了索引.但是,索引只能起作用,如果我只选择索引列.mysql索引是否依赖于所选列?

我的指数假设

我认为索引就像电话词典索引页面.例如:如果我想找到"马克".索引页面显示目录中的哪个页面字符"M".我认为和mysql一样工作.

+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| ID           | int(11)      | NO   | PRI | NULL    | auto_increment |
| Name         | varchar(100) | YES  |     | NULL    |                |
| OPERATION    | varchar(100) | YES  |     | NULL    |                |
| PID         | int(11)      | YES  |     | NULL    |                |
| CREATED_TIME | bigint(20)   | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

索引在桌子上.

    +-----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| IndexTest |          0 | PRIMARY  |            1 | ID           | A         |       10261 |     NULL | NULL   |      | BTREE      |         |               |
| IndexTest |          1 | t_dx     |            1 | CREATED_TIME | A         |         410 |     NULL | NULL   | YES  | BTREE      |         |               |
+-----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Run Code Online (Sandbox Code Playgroud)

查询使用索引:

   explain select * from IndexTest where ID < 5;
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table     | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | IndexTest | range | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using where |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+



  explain select CREATED_TIME from IndexTest where CREATED_TIME > UNIX_TIMESTAMP(CURRENT_DATE())*1000;
    +----+-------------+-----------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table     | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-----------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | IndexTest | range | t_dx          | t_dx | 9       | NULL | 5248 | Using where; Using index |
+----+-------------+-----------+-------+---------------+------+---------+------+------+--------------------------+
Run Code Online (Sandbox Code Playgroud)

查询不使用索引

    explain select count(distinct(PID)) from IndexTest where CREATED_TIME > UNIX_TIMESTAMP(CURRENT_DATE())*1000;
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | IndexTest | ALL  | t_dx          | NULL | NULL    | NULL | 10261 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+


    explain select PID from IndexTest where CREATED_TIME > UNIX_TIMESTAMP(CURRENT_DATE())*1000;
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | IndexTest | ALL  | t_dx          | NULL | NULL    | NULL | 10261 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+-------+-------------+
Run Code Online (Sandbox Code Playgroud)

Haz*_*zit 5

简答:不.

是否使用索引取决于WHERE子句中的表达式,JOINs等,而不取决于您选择的列.

但是没有例外的规则(或实际上很长的列表):

答案很长:通常不是

MySQL Optimizer使用了许多因素来确定它是否应该使用索引.

如果...,优化器可能决定忽略索引

  • 另一个(否则是非最佳的)使其无法访问表数据
  • 它无法理解表达式是常量
  • 它的估计表明它无论如何都将返回整个表格
  • 如果它的使用会导致创建一个临时文件
  • ......还有很多其他原因,其中一些似乎没有任何记录

有时候,优化器做出的选择是......呃...让我们称之为次优.那么在那些情况下你做了什么?

  • 您可以通过执行OPTIMIZE TABLE和/或帮助优化器ANALYZE TABLE.这很容易做到,有时也有帮助.
  • 您可以使用USE INDEX(indexname)FORCE INDEX(indexname)语法使用某个索引
  • 您可以使用IGNORE INDEX(indexname)语法忽略某个索引

有关MySQL文档网站上的索引提示,优化表分析表的更多详细信息.