1、索引-使用规则-验证索引效率失效(最左前缀法则、范围查询)
#索引-使用规则
##索引-使用规则-验证索引效率失效
###1、最左前缀法则:如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃了某一列,索引将部分失效(后面字段索引失效)
##通过以下来看
explain select * from tb_user where profession='软件工程' and age=31 and status='0';
explain select * from tb_user where profession='软件工程' and age=31;
explain select * from tb_user where profession='软件工程' ;
explain select * from tb_user where age=31 and status='0';
explain select * from tb_user where status='0';
##范围查询:联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效
##列子:
explain select * from tb_user where profession ='软件工程' and age>'30' and status='0';
explain select * from tb_user where profession ='软件工程' and age>='30' and status='0';
在xshell+xftp+VMware+mysql环境下:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| user |
+--------------------+
5 rows in set (0.00 sec)
mysql> use user;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
5 rows in set (0.03 sec)
mysql> insert into tb_user values(6,'不知道','177799990006','buzdao666@163.com','软件工程','31','1',0,'2001-09-20 00:00:00');
Query OK, 1 row affected (0.01 sec)
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
6 rows in set (0.00 sec)
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_email | 1 | email | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
7 rows in set (0.02 sec)
mysql> select * from tb_user where profession='软件工程' and age='31' and status='0';
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * 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_status | idx_user_pro_age_status | 208 | const,const,const | 1 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user where profession='软件工程' and age='31';
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------+------+----------+-----------------------+
| 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_status | idx_user_pro_age_status | 203 | const,const | 1 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
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_status | idx_user_pro_age_status | 201 | const | 2 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user where 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 | ALL | NULL | NULL | NULL | NULL | 6 | 16.67 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> ##即可知explain select * from tb_user where age='31' and status='0';不满足最左前缀法则
mysql> ##下面运行的语句也是不满足最左前缀法则的
mysql> explain select * from tb_user where 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)
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_status | idx_user_pro_age_status | 201 | const | 2 | 16.67 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> ###即可以知道explain select * from tb_user where profession='软件工程' and status='0';跳跃了age这个字段,即后面的status字段失效,可以从以上的key_len看出来
mysql> explain select * from tb_user where age='31' and status='0' and 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_status | idx_user_pro_age_status | 208 | const,const,const | 1 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> ##explain select * from tb_user where age='31' and status='0' and profession='软件工程';说明了最左前缀法则是要求(第一个)字段必须存在,跟其顺序没有关系
mysql> #范围查询
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_status | idx_user_pro_age_status | 203 | NULL | 1 | 16.67 | Using index condition |
+----+-------------+---------+------------+-------+-------------------------+-------------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.01 sec)
mysql> ##在age>'30'处实行了(>,<)的范围查询,所以后面的status索引失效
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_status | idx_user_pro_age_status | 208 | NULL | 1 | 16.67 | Using index condition |
+----+-------------+---------+------------+-------+-------------------------+-------------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
2、索引失效情况一、索引失效情况二
##索引失效情况一
###1、不要在索引列上进行运算操作,索引失效
explain select * from tb_user where substring(phone,11,2)='06';##使用substring截取字符串
##2、字符串类型字段使用时,不加引号,索引将失效
explain select * from tb_user where phone=177799990006;
##3、模糊查询:如果仅仅时尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效
explain select * from tb_user where profession like '软件%';##不会失效
explain select * from tb_user where profession like '%工程';##会失效
explain select * from tb_user where profession like '%工%';##会失效
##索引失效情况二
###1、or连接的条件:用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
explain select * from tb_user where id =5 or age=22;
explain select * from tb_user where phone=' 177799990007' or age=22;
##由于age没有索引,所以即使id、phone有索引,索引也会失效,所以需要针对于age也要建立索引
create index idx_user_age on tb_user(age);##创建索引后,再运行下面两个语句
explain select * from tb_user where id =5 or age=22;
explain select * from tb_user where phone=' 177799990007' or age=22;
###2、数据分布影响:如果MySQL评估使用索引比全表更慢,则不使用索引
explain select * from tb_user where phone>='177799990005';
explain select * from tb_user where phone>='177799990015';
explain select * from tb_user where phone is null;
explain select * from tb_user where phone is not null;##(取决于表中数据的分布)
在xshell+xftp+VMware+mysql环境下
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
6 rows in set (0.00 sec)
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_email | 1 | email | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
7 rows in set (0.00 sec)
mysql> select * from tb_user where phone='177799990006';
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_user where phone='177799990006';
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
| 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 | 201 | const | 1 | 100.00 | NULL |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> ###查询手机号最后两位是06的
mysql> select * from tb_user where substring(phone,11,2);##使用substring截取字符串
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
5 rows in set (0.00 sec)
mysql> select * from tb_user where substring(phone,11,2)='15';##使用substring截取字符串
Empty set (0.00 sec)
mysql> select * from tb_user where substring(phone,11,2)='06';##使用substring截取字符串
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_user where substring(phone,11,2)='06';##使用substring截取字符串
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 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 | 100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> ##即以上用substring,在索引列上进行运算操作,索引失效
mysql> ##下面演示字符串不加引号(字符串类型字段使用时,不加引号,索引失效
mysql> ##下面演示字符串不加引号(字符串类型字段使用时,不加引号,索引将失效
mysql> select * from tb_user where phone=177799990006;
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_user where phone=177799990006;
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
| 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 | 6 | 16.67 | Using where |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)
mysql> ##模糊查询:如果仅仅时尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效
mysql> select * from tb_user where profession='软件%';
Empty set (0.00 sec)
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
6 rows in set (0.00 sec)
mysql> select * from tb_user where profession like '软件%';
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
2 rows in set (0.04 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_status | idx_user_pro_age_status | 201 | NULL | 2 | 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 | 6 | 16.67 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 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 | 6 | 16.67 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> #or连接的条件:用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
6 rows in set (0.00 sec)
mysql> select * from tb_user where id=5 or age =22;
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
1 row in set (0.01 sec)
mysql> insert into tb_user values(7,'无名','177799990007','wuming666@sina,com','软件工程','22','2',0,'2001-09-08');
Query OK, 1 row affected (0.01 sec)
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
| 7 | 无名 | 177799990007 | wuming666@sina,com | 软件工程 | 22 | 2 | 0 | 2001-09-08 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
7 rows in set (0.01 sec)
mysql> select * from tb_user where id =5 or age=22;
+----+--------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+--------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 7 | 无名 | 177799990007 | wuming666@sina,com | 软件工程 | 22 | 2 | 0 | 2001-09-08 |
+----+--------+--------------+--------------------+--------------+------+--------+--------+---------------------+
2 rows in set (0.00 sec)
mysql> explain select * from tb_user where id =5 or age=22;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 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 | 7 | 26.53 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user where phone=' 177799990007' or age=22;
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
| 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 | 7 | 26.53 | Using where |
+----+-------------+---------+------------+------+----------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> ###上面演示两个or的语句,索引失效的原因是age没有索引
mysql> ##由于age没有索引,所以即使id、phone有索引,索引也会失效,所以需要针对于age也要建立索引
mysql> create index idx_user_age on tb_user(age);
Query OK, 0 rows affected (0.16 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select * from tb_user where phone=' 177799990007' or age=22;
+----+-------------+---------+------------+-------------+-----------------------------+-----------------------------+---------+------+------+----------+-------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------------+-----------------------------+-----------------------------+---------+------+------+----------+-------------------------------------------------------+
| 1 | SIMPLE | tb_user | NULL | index_merge | idx_user_phone,idx_user_age | idx_user_phone,idx_user_age | 201,2 | NULL | 3 | 100.00 | Using union(idx_user_phone,idx_user_age); Using where |
+----+-------------+---------+------------+-------------+-----------------------------+-----------------------------+---------+------+------+----------+-------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user where id =5 or age=22;
+----+-------------+---------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+
| 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.00 sec)
mysql>
3、SQL提示
##索引-使用规则-SQL提示
##SQL提示:SQL提示,是优化数据库的一个重要手段,就是在SQL语句中加入一些为人的提示来达到优化操作的目的
use index:##告诉数据库用哪个索引(建议)
explain select * from tb_user use index(idx_user_pro) where profession='软件工程';
ignore index:##告诉数据库不要哪个索引
explain select * from tb_user ignore index(idx_user_pro) where profession='软件工程';
force index:##告诉数据库必须用哪个索引(强制)
explain select * from tb_user force index(idx_user_pro) where profession='软件工程';
在xshell+xftp+VMware+mysql环境下
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
| 7 | 无名 | 177799990007 | wuming666@sina,com | 软件工程 | 22 | 2 | 0 | 2001-09-08 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
7 rows in set (0.00 sec)
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_email | 1 | email | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_age | 1 | age | A | 6 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
8 rows in set (0.01 sec)
mysql> create index idx_user_pro on tb_user(profession);
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
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 | 201 | const | 3 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.01 sec)
mysql> explain select * from tb_user ignore 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_age_status | idx_user_pro_age_status | 201 | const | 3 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user ignore index(idx_user_pro_age_status) 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 | 201 | const | 3 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user force 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 | 201 | const | 3 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+---------------+--------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
4、覆盖索引&回表查询
##索引-使用规则-覆盖索引&回表查询
###覆盖索引:尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select*
explain select id,profession from tb_user where profession='软件工程' and age='31' and status=0;
explain select id,profession,age,status from tb_user where profession='软件工程' and age='31' and status=0;
explain select id,profession,age,status,name from tb_user where profession='软件工程' and age='31' and status=0;
explain select * from tb_user where profession='软件工程' and age='31' and status=0;
###特别重视:
using index condition:查找使用了索引,但是需要回表查询数据
using where,using index:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据
在xshell+xftp+VMware+mysql环境下
mysql> drop index idx_user_age on tb_user;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop index idx_user_pro on tb_user;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop index idx_user_email on tb_user;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
6 rows in set (0.01 sec)
mysql> select id,profession from tb_user where profession='软件工程' and age='31' and status=0;
+----+--------------+
| id | profession |
+----+--------------+
| 6 | 软件工程 |
+----+--------------+
1 row in set (0.00 sec)
mysql> select * from tb_user where profession='软件工程' and age='31' and status=0;
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
+----+-----------+--------------+-------------------+--------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * 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_status | idx_user_pro_age_status | 208 | const,const,const | 1 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select id,profession 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_status | idx_user_pro_age_status | 208 | 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 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_status | idx_user_pro_age_status | 208 | const,const,const | 1 | 100.00 | Using where; Using index |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------------+------+----------+--------------------------+
1 row in set, 1 warning (0.01 sec)
mysql> explain select id,profession,age 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_status | idx_user_pro_age_status | 208 | 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_status | idx_user_pro_age_status | 208 | const,const,const | 1 | 100.00 | Using index condition |
+----+-------------+---------+------------+------+-------------------------+-------------------------+---------+-------------------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
5、前缀索引、单列&联合索引
##索引-使用规则-前缀索引
###前缀索引:当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时。浪费大量的磁盘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;
##索引-使用规则-单列&联合索引
###单列索引与联合索引
####单列索引:即一个索引只包含单个列
####联合索引:即一个索引包含了多个列
explain select id,phone,name from tb_user use index(idx_phone_name) where phone='177799990003' and name='赵云';
####在业务场景中,如果存在多个查询条件,考虑对于查询字段建立索引时,建议建立联合索引,而非单列索引
####多条件联合查询时,MySQL优化器会评估哪个字段的索引效率高,会选择该索引完成本次查询(特别注重)
在xshell+xftp+VMware+mysql环境下
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
| 7 | 无名 | 177799990007 | wuming666@sina,com | 软件工程 | 22 | 2 | 0 | 2001-09-08 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
7 rows in set (0.01 sec)
mysql> insert into tb_user values(8,'郝佳','177799990008','177799990@139.com','计算机','34','1',1,'2001-05-07 00:00:00');
Query OK, 1 row affected (0.06 sec)
mysql> select * from tb_user;
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
| 1 | 吕布 | 177799990000 | lvbu666@163.com | 软件工程 | 23 | 1 | 6 | 2001-02-02 00:00:00 |
| 2 | 曹操 | 177799990001 | caocao666@qq.com | 应用数学 | 53 | 1 | 0 | 2001-04-03 00:00:00 |
| 3 | 赵云 | 177799990003 | 177799990@139.com | 英语 | 34 | 1 | 2 | 2002-03-05 00:00:00 |
| 4 | 兰陵王 | 177799990002 | lanlw666@126.com | 工程造价 | 44 | 1 | 1 | 2001-04-19 00:00:00 |
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
| 6 | 不知道 | 177799990006 | buzdao666@163.com | 软件工程 | 31 | 1 | 0 | 2001-09-20 00:00:00 |
| 7 | 无名 | 177799990007 | wuming666@sina,com | 软件工程 | 22 | 2 | 0 | 2001-09-08 |
| 8 | 郝佳 | 177799990008 | 177799990@139.com | 计算机 | 34 | 1 | 1 | 2001-05-07 00:00:00 |
+----+-----------+--------------+--------------------+--------------+------+--------+--------+---------------------+
8 rows in set (0.00 sec)
mysql> select count(*) from tb_user;
+----------+
| count(*) |
+----------+
| 8 |
+----------+
1 row in set (0.06 sec)
mysql> select count(email) from tb_user;
+--------------+
| count(email) |
+--------------+
| 8 |
+--------------+
1 row in set (0.00 sec)
mysql> select count(distinct email) from tb_user;
+-----------------------+
| count(distinct email) |
+-----------------------+
| 7 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select count(distinct email)/count(*) from tb_user;
+--------------------------------+
| count(distinct email)/count(*) |
+--------------------------------+
| 0.8750 |
+--------------------------------+
1 row in set (0.01 sec)
mysql> select count(distinct substring(email,1,11))/count(*) from tb_user;
+------------------------------------------------+
| count(distinct substring(email,1,11))/count(*) |
+------------------------------------------------+
| 0.8750 |
+------------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(distinct substring(email,1,10))/count(*) from tb_user;
+------------------------------------------------+
| count(distinct substring(email,1,10))/count(*) |
+------------------------------------------------+
| 0.8750 |
+------------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(distinct substring(email,1,12))/count(*) from tb_user;
+------------------------------------------------+
| count(distinct substring(email,1,12))/count(*) |
+------------------------------------------------+
| 0.8750 |
+------------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(distinct substring(email,1,9))/count(*) from tb_user;
+-----------------------------------------------+
| count(distinct substring(email,1,9))/count(*) |
+-----------------------------------------------+
| 0.8750 |
+-----------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(distinct substring(email,1,4))/count(*) from tb_user;
+-----------------------------------------------+
| count(distinct substring(email,1,4))/count(*) |
+-----------------------------------------------+
| 0.8750 |
+-----------------------------------------------+
1 row in set (0.01 sec)
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
6 rows in set (0.02 sec)
mysql> create index idx_email_5 on tb_user(email(5));
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_email_5 | 1 | email | A | 7 | 5 | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
7 rows in set (0.04 sec)
mysql> select * from tb_user where email='daqiao666@sina.com';
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
| id | name | phone | email | profession | age | gender | status | createtime |
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
| 5 | 大乔 | 177799990005 | daqiao666@sina.com | 舞蹈 | 22 | 2 | 0 | 2001-02-07 00:00:00 |
+----+--------+--------------+--------------------+------------+------+--------+--------+---------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_user where email='daqiao666@sina.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 | 21 | const | 1 | 100.00 | Using where |
+----+-------------+---------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> show index from tb_user;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user | 0 | PRIMARY | 1 | id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| tb_user | 0 | idx_user_phone | 1 | phone | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 1 | profession | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_user_pro_age_status | 3 | status | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tb_user | 1 | idx_email_5 | 1 | email | A | 7 | 5 | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
7 rows in set (0.01 sec)
mysql> select id,phone,name from tb_user where phone='177799990003' and name='赵云';
+----+--------------+--------+
| id | phone | name |
+----+--------------+--------+
| 3 | 177799990003 | 赵云 |
+----+--------------+--------+
1 row in set (0.01 sec)
mysql> explain select id,phone,name from tb_user where phone='177799990003' 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_name | idx_user_phone | 201 | const | 1 | 100.00 | NULL |
+----+-------------+---------+------------+-------+------------------------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
mysql> create index idx_phone_name on tb_user(phone,name);
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop index idx_phone_name on tb_user;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create unique index idx_phone_name on tb_user(phone,name);
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select id,phone,name from tb_user where phone='177799990003' 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_phone_name,idx_user_name | idx_user_phone | 201 | const | 1 | 100.00 | NULL |
+----+-------------+---------+------------+-------+---------------------------------------------+----------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select id,phone,name from tb_user use index(idx_phone_name) where phone='177799990003' and name='赵云';
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | tb_user | NULL | const | idx_phone_name | idx_phone_name | 402 | const,const | 1 | 100.00 | Using index |
+----+-------------+---------+------------+-------+----------------+----------------+---------+-------------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql>
6、索引设计原则
##索引-使用规则-索引设计原则
/*
1、针对于数据量较大,且查询比较频繁的表建立索引
2、针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引
3、尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高
4、如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引
5、尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率
6、要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率
7、如果索引列不能存储NLULL值,请在创建表时使用NOT NULL 约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地
*/