MySQL之索引使用原则详解(验证索引效率,SQL提示等)

索引使用

  • 验证索引效率

在未建立索引之前,执行如下SQL语句,查看SQL的耗时

select *  from tb_user where id = 1;

针对字段创建索引

create index idx_sku_sn on tb_sku(sn) ;

针对于用户量大的表中,添加索引要比没有添加索引的字段查询速度快。

  • 最左前缀法则

如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始, 并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(后面的字段索引失效)。

mysql> explain select * from tb_user where profession = '通讯工程' and age = 33 and status = '0';
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref               | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | const,const,const |    1 |   100.00 | Using index condition |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
#如图所示,如果删除了条件profession则不满足最左前缀法则,为nullmysql> explain select * from tb_user where  age = 33 and status = '0';
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    6 |    16.67 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)#如果删除age条件,那么会执行profession字段,不会执行status字段
mysql> explain select * from tb_user where  profession = '通讯工程' and status = '0';
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 47      | const |    1 |    16.67 | Using index condition |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
  • 范围查询

联合索引中,出现范围查询(>,<)范围查询右侧的列索引失效

#范围查询右边的列将会失效
mysql> explain select * from tb_user where profession = '软件工程' and age > 30 and status = '0';
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | range | idx_user_pro_age_sta | idx_user_pro_age_sta | 49      | NULL |    2 |    10.00 | Using index condition |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)#如果将范围修改为>=那么索引长度为54
mysql> explain select * from tb_user where profession = '软件工程' and age >= 30 and status = '0';+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | range | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | NULL |    2 |    10.00 | Using index condition |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
  • 索引列运算

不要在索引列上进行运算操作,索引将失效,性能将会降低

#查看phone的单列索引
mysql> select * from tb_user where phone = '17799990018';
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
| id | name      | phone       | email                | profession   | age  | gender | status | createtime          |
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
| 18 | 狄仁杰    | 17799990018 | jujiamlm8166@163.com | 国际贸易     |   30 | 1      | 0      | 2007-03-12 00:00:00 |
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)mysql> explain select * from tb_user where phone = '17799990018';
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type  | possible_keys  | key            | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | const | idx_user_phone | idx_user_phone | 46      | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)#如果添加函数运算,索引将会失效
mysql> select * from tb_user where substring(phone,10,2) = '18';
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
| id | name      | phone       | email                | profession   | age  | gender | status | createtime          |
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
| 18 | 狄仁杰    | 17799990018 | jujiamlm8166@163.com | 国际贸易     |   30 | 1      | 0      | 2007-03-12 00:00:00 |
+----+-----------+-------------+----------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)mysql> explain select * from tb_user where substring(phone,10,2) = '18';
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   18 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
  • 字符串不加引号

字符串类型字段使用时,不加引号,索引将失效

mysql> explain select * from tb_user where phone = '17799990018';
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type  | possible_keys  | key            | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | const | idx_user_phone | idx_user_phone | 46      | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)#如果去掉引号,就会失效
mysql> explain select * from tb_user where phone = 17799990018;
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys  | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | idx_user_phone | NULL | NULL    | NULL |   18 |    10.00 | Using where |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)
  • 模糊查询

如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效

mysql> explain select * from tb_user where profession like '软件%';
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | range | idx_user_pro_age_sta | idx_user_pro_age_sta | 47      | NULL |    4 |   100.00 | Using index condition |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
#如果前面加入百分号则查询不到
mysql> explain select * from tb_user where profession like '%工程';
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   18 |    11.11 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
  • or连接的条件

用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到

mysql> explain select * from tb_user where id = 10 or age = 23;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL |   18 |    15.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

 由于age没有索引,所以即使id,phone有索引,索引也会失效。所以需要针对于age也要建立索引。

mysql> create index idx_user_age on tb_user(age);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> explain select * from tb_user where id = 10 or age = 23;
+----+-------------+---------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+
| id | select_type | table   | partitions | type        | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                                          |
+----+-------------+---------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+
|  1 | SIMPLE      | tb_user | NULL       | index_merge | PRIMARY,idx_user_age | PRIMARY,idx_user_age | 4,2     | NULL |    3 |   100.00 | Using union(PRIMARY,idx_user_age); Using where |
+----+-------------+---------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+
1 row in set, 1 warning (0.02 sec)

- 数据分布影响

如果MySQL评估使用索引比全表更慢,则不使用索引

#由于phone的号码尾数全部大于十,所以全文扫描更加方便。而不走索引扫描
mysql> explain select * from tb_user where phone  >= '17799990000';
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys  | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | idx_user_phone | NULL | NULL    | NULL |   18 |   100.00 | Using where |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from tb_user where phone  >= '17799990013';
+----+-------------+---------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
| id | select_type | table   | partitions | type  | possible_keys  | key            | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+---------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | range | idx_user_phone | idx_user_phone | 46      | NULL |    6 |   100.00 | Using index condition |
+----+-------------+---------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

查询时MySQL会评估,走索引快,还是全表扫描快,如果全表 扫描更快,则放弃索引走全表扫描。 因此,is null 、is not null是否走索引,得具体情况具体 分析,并不是固定的。

mysql> explain select * from tb_user where profession is null;
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 47      | const |    1 |   100.00 | Using index condition |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from tb_user where profession is not null;
+----+-------------+---------+------------+------+----------------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys        | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+----------------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | idx_user_pro_age_sta | NULL | NULL    | NULL |   18 |   100.00 | Using where |
+----+-------------+---------+------------+------+----------------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

 

  • SQL提示

SQL提示,是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优 化操作的目的。

A. 执行SQL : explain select * from tb_user where profession = '软件工程';

mysql> explain select * from tb_user where profession = '软件工程';
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 47      | const |    4 |   100.00 | NULL  |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
查找走了联合索引

B. 执行SQL,创建profession的单列索引:create index idx_user_pro on tb_user(profession);

mysql> create index idx_user_pro on tb_user(profession);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

 C. 创建单列索引后,再次执行A中的SQL语句,查看执行计划,看看到底走哪个索引。

mysql> explain select * from tb_user where profession = '软件工程';
+----+-------------+---------+------------+------+-----------------------------------+----------------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys                     | key                  | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+-----------------------------------+----------------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta,idx_user_pro | idx_user_pro_age_sta | 47      | const |    4 |   100.00 | NULL  |
+----+-------------+---------+------------+------+-----------------------------------+----------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

测试结果,我们可以看到,possible_keys中 idx_user_pro_age_sta,idx_user_pro 这两个 索引都可能用到,最终MySQL选择了idx_user_pro_age_sta索引。这是MySQL自动选择的结果。

1). use index : 建议MySQL使用哪一个索引完成此次查询(仅仅是建议,mysql内部还会再次进 行评估)。

explain select * from tb_user use index(idx_user_pro) where profession = '软件工
程';mysql> explain select * from tb_user use index(idx_user_pro) where profession = '软件工'> 程';
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key          | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro  | idx_user_pro | 47      | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

 2). ignore index : 忽略指定的索引。

explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工
程';

 3). force index : 强制使用索引。

explain select * from tb_user force index(idx_user_pro) where profession = '软件工
程';

 

  • 覆盖索引

尽量使用覆盖索引,减少select *。 那么什么是覆盖索引呢?

覆盖索引是指 查询使用了索引,并 且需要返回的列,在该索引中已经全部能够找到 。

mysql> explain select id,profession,age,status from tb_user where profession = '软件工程' and age = 31 and status = '0';
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+--------------------------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref               | rows | filtered | Extra                    |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+--------------------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | const,const,const |    1 |   100.00 | Using where; Using index |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select id,profession,age,status,name from tb_user where profession = '软件工程' and age = 31 and status = '0';
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
| id | select_type | table   | partitions | type | possible_keys        | key                  | key_len | ref               | rows | filtered | Extra                 |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | const,const,const |    1 |   100.00 | Using index condition |
+----+-------------+---------+------------+------+----------------------+----------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
extra含义
using where;using index查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要查询数据
using index conition查找使用了索引,但是需要回表查询数据

思考题:

一张表, 有四个字段(id, username, password, status), 由于数据量大, 需要对 以下SQL语句进行优化, 该如何进行才是最优方案:

select id,username,password from tb_user where username = 'itcast';

答案: 针对于 username, password建立联合索引, sql为: create index idx_user_name_pass on tb_user(username,password); 这样可以避免上述的SQL语句,在查询的过程中,出现回表查询。

  • 前缀索引

当字段类型为字符串(varchar,text,longtext等)时,有时候需要索引很长的字符串,这会让 索引变得很大,查询时,浪费大量的磁盘IO, 影响查询效率。此时可以只将字符串的一部分前缀,建 立索引,这样可以大大节约索引空间,从而提高索引效率。

语法:

create index idx_xxxx on table_name(column(n)) ;

前缀长度

可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值, 索引选择性越高则查询效率越高, 唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。

select count(distinct email) / count(*) from tb_user ;
select count(distinct substring(email,1,5)) / count(*) from tb_user ;
mysql> select count(distinct substring(email,1,10))/count(*) from tb_user;
+------------------------------------------------+
| count(distinct substring(email,1,10))/count(*) |
+------------------------------------------------+
|                                         1.0000 |
+------------------------------------------------+
1 row in set (0.01 sec)mysql> select count(distinct substring(email,1,9))/count(*) from tb_user;
+-----------------------------------------------+
| count(distinct substring(email,1,9))/count(*) |
+-----------------------------------------------+
|                                        0.9444 |
+-----------------------------------------------+
1 row in set (0.00 sec)mysql> create index idx_email_5 on tb_user(email(5));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> select * from tb_user where email = 'jingke123@163.com';
+----+--------+-------------+-------------------+------------+------+--------+--------+---------------------+
| id | name   | phone       | email             | profession | age  | gender | status | createtime          |
+----+--------+-------------+-------------------+------------+------+--------+--------+---------------------+
| 11 | 荆轲   | 17799990011 | jingke123@163.com | 会计       |   29 | 1      | 0      | 2001-05-11 00:00:00 |
+----+--------+-------------+-------------------+------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)mysql> explain select * from tb_user where email = 'jingke123@163.com';
+----+-------------+---------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | ref  | idx_email_5   | idx_email_5 | 23      | const |    1 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
  • 单列索引和联合索引

单列索引:即一个索引只包含单个列。

联合索引:即一个索引包含了多个列。

 

在查询出来的索引中,既有单列索引,又有联合索引

 

 在and连接的两个字段 phone、name上都是有单列索引的,但是 最终mysql只会选择一个索引,也就是说,只能走一个字段的索引,此时是会回表查询的。然后我们创建一个phone和name字段的联合索引查询一下执行:

mysql>  create unique index idx_user_phone_name on tb_user(phone,name);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> explain select id,phone,name from tb_user where phone = '17799990002' and name = '赵云';
+----+-------------+---------+------------+-------+--------------------------------------------------+----------------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type  | possible_keys                                    | key            | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+-------+--------------------------------------------------+----------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tb_user | NULL       | const | idx_user_phone,idx_user_phone_name,idx_user_name | idx_user_phone | 46      | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+-------+--------------------------------------------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

此时,查询时,就走了联合索引,而在联合索引中包含 phone、name的信息,在叶子节点下挂的是对 应的主键id,所以查询是无需回表查询的。

在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引, 而非单列索引。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439015.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基础算法练习】单调队列与单调栈模板

文章目录 单调栈模板题代码模板算法思想 单调队列模板题代码模板算法思想 单调栈 模板题 题目链接&#xff1a;ACwing 830. 单调栈 代码模板 #include <iostream> #include <vector> #include <stack>using namespace std;const int N 100010;vector<…

STM32标准库+HAL库 | 输入捕获测量PWM的脉冲频率+占空比

提醒&#xff1a;本文的代码Demo中使用的是&#xff0c;单通道捕捉采集PWM输入信号的频率占空比。 在上一篇博客中已经讲解了过PWM输出配置&#xff0c;本文主要讲解TIM输入捕获配置。STM32标准库HAL库 | 高精度动态调节PWM输出频率占空比_hal库改变pwm频率-CSDN博客 目录 1…

Mac安装配置maven

Mac安装配置maven 官网下载地址&#xff1a;https://maven.apache.org/download.cgi 下载好以后解压配置 maven 环境变量 打开终端&#xff0c;输入命令打开配置文件./bash_profile open ~/.bash_profile输入i进入编辑模式,进行maven配置; MAVEN_HOME为maven的本地路径 ex…

机器学习3-简单线性回归

需求&#xff1a; 现在要根据学生的学习时间来预测学习成绩&#xff0c;给出现有数据&#xff0c;用来训练模型并预测新数据。 分析&#xff1a; 使用线性回归模型。 代码&#xff1a; import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection i…

蓝桥杯备战——8.DS1302时钟芯片

1.分析原理图 由上图可以看到&#xff0c;芯片的时钟引脚SCK接到了P17,数据输出输入引脚IO接到P23,复位引脚RST接到P13。 2.查阅DS1302芯片手册 具体细节还需自行翻阅手册&#xff0c;我只截出重点部分 总结&#xff1a;数据在上升沿写出&#xff0c;下降沿读入&#xff0c;…

PDF控件Spire.PDF for .NET【安全】演示:使用 C# 检测签名的 PDF 是否被修改

对 PDF 文档进行数字签名后&#xff0c;PDF 将被锁定以防止更改或允许检测更改。在本文中&#xff0c;我们将介绍如何使用 Spire.PDF 检测签名的 PDF 是否被修改。 Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作 PDF 文档。使用 Spire…

鸿蒙首批原生应用!无感验证已完美适配鸿蒙系统

顶象无感验证已成功适配鸿蒙系统&#xff0c;成为首批鸿蒙原生应用&#xff0c;助力鸿蒙生态的快速发展。 作为全场景分布式操作系统&#xff0c;鸿蒙系统旨在打破不同设备之间的界限&#xff0c;实现极速发现、极速连接、硬件互助、资源共享。迄今生态设备数已突破8亿台&…

结构体与共用体基础

结构体基础用法与共用体简述 1.结构体的定义2.结构体声明及使用3.结构体成员初始化4.结构体占用空间探究4.1 结构体成员所在地址4.2 按地址值访问结构体内容4.3 内存对齐 5.共用体6.总结 1.结构体的定义 之前的课程中&#xff0c;我们介绍了很多数据类型&#xff0c;如整形、浮…

测试用例级别该如何定义 ? 在工作中该如何应用它 ? 把握好这5个场景即可。

1.级别的作用 在编写测试用例的过程中&#xff0c;用例的级别经常是一个不可缺少的字段 &#xff0c;本篇幅就来聊下这个字段 &#xff0c;首先从它的作用是什么呢 &#xff1f;我觉得主要有两点 &#xff0c;分别是 &#xff1a; 用于测试用例不同套件的选取 &#xff0c;即用…

MMCLMC公差计算.exe

一、概要 软件及完整代码请戳这里&#xff1a;MMC&LMC公差计算软件及代码 图1 软件操作界面 本软件功能主要是根据实际应用选择MMR或者LMR原则&#xff0c;输入基本尺寸、形位公差尺寸和实际测量尺寸&#xff0c;即可计算出对应的公差值。以孔的MMR为例见如图2、3&#xf…

Java - JDBC

Java - JDBC 文章目录 Java - JDBC引言JDBC1 什么是JDBC2 MySQL数据库驱动3 JDBC开发步骤4 具体介绍 引言 思考: 当下我们如何操作数据库&#xff1f; 使用客户端工具访问数据库&#xff0c;手工建立连接&#xff0c;输入用户名和密码登录。编写SQL语句&#xff0c;点击执行…

【论文阅读|半监督小苹果检测方法S3AD】

论文题目 &#xff1a; : Semi-supervised Small Apple Detection in Orchard Environments 项目链接&#xff1a;https://www.inf.uni-hamburg.de/en/inst/ab/cv/people/wilms/mad.html 摘要&#xff08;Abstract&#xff09; 农作物检测是自动估产或水果采摘等精准农业应用不…