author:JevonWei

版权声明:原创作品


索引基础:

索引:提取索引的创建在的表上字段中的数据,构建出一个独特的数据结构;

索引的作用:加速查询操作;副作用:降低写操作性能;
表中数据子集:把表中某个或某些字段的数据提取出来另存为一个特定数据结构组织的数据;
某个字段或某些字段:WHERE子句中用到的字段; 索引类型:B+ TREE Index,HASH Index、Fulltext Index、Spacial Index
B+ TREE:顺序存储,每一个叶子结点到根结点的距离相同;左前缀索引,适合于范围类型的数据查询; 适用于B+ TREE索引的查询类型:全键值、键值范围或键前缀;
全值匹配:精确匹配某个值;
WHERE COLUMN = 'value';
匹配最左前缀:只精确匹配起头的部分;
WEHRE COLUMN LIKE 'PREFIX%';
匹配范围值:
精确匹配某一列,范围匹配另一列;
只用访问索引的查询:覆盖索引;
index(Name)
SELECT Name FROM students WHERE Name LIKE 'L%'; 不适用B+ TREE索引:
如果查询条件不是从最左侧列开始,索引无效;
index(age,Fname), WHERE Fname='Jerry';(无效) , WHERE age>30 AND Fname='Smith';
不能跳过索引中的某列;
index(name,age,gender)
WHERE name='black' and age > 30;
WHERE name='black' AND gender='F'; (无效不可用)
如果查询中的某个列是为范围查询,那么其右侧的列都无法再使用索引优化查询;
WHERE age>30 AND Fname='Smith' (无效) Hash索引:基于哈希表实现,特别适用于值的精确匹配查询; 适用场景:
只支持等值比较查询,例如=, IN(), <=> 不用场景:
所有非精确值查询;MySQL仅对memory存储引擎支持显式的hash索引; 索引优点:
降低需要扫描的数据量,减少IO次数;
可以帮助避免排序操作,避免使用临时表;
帮助将随机IO转为顺序IO; 高性能索引策略:
(1) 在WHERE中独立使用列,尽量避免其参与运算;
WHERE age+2 > 32 ; (索引失效)
(2) 左前缀索引:索引构建于字段的最左侧的多少个字符,要通过索引选择性来评估
索引选择性:不重复的索引值和数据表的记录总数的比值;
(3) 多列索引:
AND连接的多个查询条件更适合使用多列索引,而非多个单键索引;
(4) 选择合适的索引列次序:选择性最高的放左侧; EXPLAIN来分析索引有效性: EXPLAIN [explain_type] SELECT select_options 分析select语句索引的有效性 explain_type:
EXTENDED
| PARTITIONS 输出结果:
id: 1
select_type: SIMPLE
table: students
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra: id:当前查询语句中,第个SELECT语句的编号; 复杂的查询的类型主要三种:
简单子查询
用于FROM中的子查询
联合查询 注意:联合查询的分析结果会出现一个额外的匿名临时表; select_type:查询类型:
简单查询:SIMPLE
复杂查询:
简单子查询:SUBQUERY
用于FROM中的子查询:DERIVED
联合查询中的第一个查询:PRIMARY
联合查询中的第一个查询之后的其它查询:UNION
联合查询生成的临时表:UNION RESULT table:查询针对的表; type:关联类型,或称为访问类型,即MySQL如何去查询表中的行
ALL:全表扫描;
index:根据索引的顺序进行的全表扫描;但同时如果Extra列出现了"Using index”表示使用了覆盖索引;
range:有范围限制地根据索引实现范围扫描;扫描位置始于索引中的某一项,结束于另一项;
ref:根据索引返回的表中匹配到某单个值的所有行(匹配给定值的行不止一个);
eq_ref:根据索引返回的表中匹配到某单个值的单一行,仅返回一个行,但需要与某个额外的参考值比较,而不是常数;
const,system:与某个常数比较,且只返回一行; possiable_keys:查询中可能会用到的索引; key:查询中使用的索引; key_len:查询中用到的索引长度; ref:在利用key字段所显示的索引完成查询操作时所引用的列或常量值; rows:MySQL估计出的为找到所有的目标项而需要读取的行数; Extra:额外信息
Using index:使用了覆盖索引进行的查询;
Using where:拿到数据后还要再次进行过滤;
Using temporary:使用了临时表以完成查询;
Using filesort:对结果使用了一个外部索引排序;

实战:

数据库中插入大量数据,从而创建索引

[root@danran ~]# for i in {5..1000};do mysql -e "INSERT INTO mydb.students VALUES ('$i','stu$i',$[$RANDOM%100+1],'F','major$i')";done
[root@danran ~]# for i in {1001..2000};do mysql -e "INSERT INTO mydb.students VALUES ('$i','stu$i',$[$RANDOM%100+1],'M','major$i')";done

单键索引

MariaDB [(none)]> create database mydb;  创建数据库
MariaDB [(none)]> use mydb;
MariaDB [mydb]> create table students (stuid INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,name VARCHAR(200),age TINYINT UNSIGNED,gender ENUM('F','M'),major VARCHAR(200));
创建students表,子段为stuid,name,age,gender,major
MariaDB [mydb]> INSERT INTO students (name,age,gender,major) VALUE('dan',16,'M','jian'),('ran',20,'F','quan'),('jevon',19,'M','qiang'),('wei',15,'F','wu die');
插入数据到students表
MariaDB [mydb]> EXPLAIN SELECT name,age FROM students WHERE age >=15; 分析select语句索引的有效性
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 1819 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
MariaDB [mydb]> HELP CREATE INDEX 查看索引创建帮助 创建索引
MariaDB [mydb]> CREATE INDEX name ON students(name); \\根据students表的name字段创建索引name 显示students表的索引信息
MariaDB [mydb]> SHOW INDEXES FROM students;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| students | 0 | PRIMARY | 1 | stuid | A | 2203 | NULL | NULL | | BTREE | | |
| students | 1 | name | 1 | name | A | 244 | NULL | NULL | YES | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 显示select语句的索引有效性
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name = 'stu1002';
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+
| 1 | SIMPLE | students | ref | name | name | 203 | const | 1 | Using index condition |
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+ 显示select语句等值查询的索引有效性
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name = 'stu100%';
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+
| 1 | SIMPLE | students | ref | name | name | 203 | const | 1 | Using index condition |
+------+-------------+----------+------+---------------+------+---------+-------+------+-----------------------+ 显示select语句范围查询的索引有效性
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'stu100%';
+------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+
| 1 | SIMPLE | students | range | name | name | 203 | NULL | 11 | Using index condition |
+------+-------------+----------+-------+---------------+------+---------+------+------+-----------------------+

多键索引

创建多键索引
MariaDB [mydb]> CREATE INDEX name_and_age ON students(name,age); 根据students表的name和age字段创建name_and_age多键索引 显示students表的索引信息,其中包含name单键索引和name_and_age多键索引
MariaDB [mydb]> SHOW INDEXES FROM students;
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| students | 0 | PRIMARY | 1 | stuid | A | 1765 | NULL | NULL | | BTREE | | |
| students | 1 | name_and_age | 1 | name | A | 160 | NULL | NULL | YES | BTREE | | |
| students | 1 | name_and_age | 2 | age | A | 160 | NULL | NULL | YES | BTREE | | |
| students | 1 | name | 1 | name | A | 160 | NULL | NULL | YES | BTREE | | |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 有多键索引使用时,单键索引失效
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'stu100%';
+------+-------------+----------+-------+-------------------+------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+-------------------+------+---------+------+------+-----------------------+
| 1 | SIMPLE | students | range | name,name_and_age | name | 203 | NULL | 11 | Using index condition |
+------+-------------+----------+-------+-------------------+------+---------+------+------+-----------------------+ 删除单键name索引
MariaDB [mydb]> DROP INDEX name ON students; 删除单键name索引后,name_and_age多键索引依然存在
MariaDB [mydb]> SHOW INDEXES FROM students;
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| students | 0 | PRIMARY | 1 | stuid | A | 1630 | NULL | NULL | | BTREE | | |
| students | 1 | name_and_age | 1 | name | A | 1630 | NULL | NULL | YES | BTREE | | |
| students | 1 | name_and_age | 2 | age | A | 1630 | NULL | NULL | YES | BTREE | | |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 显示select语句的有效索引为多键索引name_and_age
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'stu100%';
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+
| 1 | SIMPLE | students | range | name_and_age | name_and_age | 203 | NULL | 11 | Using index condition |
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+ 多键索引name_and_age时,跳过name键直接使用age键时,索引无效,如下
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE age >=50;
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 1630 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+ 多键索引name_and_age时,直接使用单键name或使用多键时,索引有效(以下因为name键过滤太过故索引无效)
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'stu%' AND age >=50;
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | students | ALL | name_and_age | NULL | NULL | NULL | 1630 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+------+-------------+ 当多键索引过滤不多时,索引可以正常使用,故key索引键值正常显示
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'stu100%' AND age >=50;
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+
| 1 | SIMPLE | students | range | name_and_age | name_and_age | 205 | NULL | 11 | Using index condition |
+------+-------------+----------+-------+---------------+--------------+---------+------+------+-----------------------+

多表查询的索引信息

显示select语句多表查询
MariaDB [mydb]> SELECT * FROM students WHERE age = 100 UNION SELECT * FROM students WHERE name LIKE 'stu100%'; 显示select语句多表查询的有效索引信息
MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE age = 100 UNION SELECT * FROM students WHERE name LIKE 'stu100%';
+------+--------------+------------+-------+---------------+--------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+------------+-------+---------------+--------------+---------+------+------+-----------------------+
| 1 | PRIMARY | students | ALL | NULL | NULL | NULL | NULL | 1630 | Using where |
| 2 | UNION | students | range | name_and_age | name_and_age | 203 | NULL | 11 | Using index condition |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
+------+--------------+------------+-------+---------------+--------------+---------+------+------+-----------------------+

等值查询的有效索引

MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE stuid=4;
+------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | students | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+------+-------------+----------+-------+---------------+---------+---------+-------+------+-------+

范围查询的有效索引

MariaDB [mydb]> EXPLAIN SELECT * FROM students WHERE stuid IN (1,77,1200,1300);
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | students | range | PRIMARY | PRIMARY | 4 | NULL | 4 | Using where |
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+

索引显示的选项:

id:select语句的ID
select_type:查询类型:
简单查询:SIMPLE
复杂查询:
简单子查询:SUBQUERY
用于FROM中的子查询:DERIVED
联合查询中的第一个查询:PRIMARY
联合查询中的第一个查询之后的其它查询:UNION
联合查询生成的临时表:UNION RESULT
table:查询针对的表;
type:关联类型,或称为访问类型,即MySQL如何去查询表中的行
ALL:全表扫描;表示无索引可用或索引过滤的行太多似无索引过滤
index:根据索引的顺序进行的全表扫描;但同时如果Extra列出现了"Using index”表示使用了覆盖索引;
range:有范围限制地根据索引实现范围扫描;扫描位置始于索引中的某一项,结束于另一项;
ref:根据索引返回的表中匹配到某单个值的所有行(匹配给定值的行不止一个);
eq_ref:根据索引返回的表中匹配到某单个值的单一行,仅返回一个行,但需要与某个额外的参考值比较,而不是常数;
const,system:与某个常数比较,且只返回一行;
possiable_keys:查询中可能会用到的索引;
key:查询中使用的索引;
key_len:查询中用到的索引长度;
ref:在利用key字段所显示的索引完成查询操作时所引用的列或常量值;
rows:MySQL估计出的为找到所有的目标项而需要读取的行数;
Extra:额外信息
Using index:使用了覆盖索引进行的查询;
Using where:拿到数据后还要再次进行过滤;
Using temporary:使用了临时表以完成查询;
Using filesort:对结果使用了一个外部索引排序;

Mysql实战之索引的更多相关文章

  1. MySQL实战 | 04 为什么要使用索引?

    原文链接:MySQL实战 | 为什么要使用索引? 用过 MySQL 的应该都知道索引是干啥的吧,应该多少都设置过索引,但是若是问你索引是怎么实现的,你能说上来吗? 索引是什么? MySQL 官方对索引 ...

  2. Mysql实战45讲 05讲深入浅出索引(下)极客时间 读书笔记

    极客时间 Mysql实战45讲 04讲深入浅出索引(下)极客时间 笔记体会: 回表:回到主键索引树搜索的过程,称为回表覆盖索引:某索引已经覆盖了查询需求,称为覆盖索引,例如:select ID fro ...

  3. Mysql实战45讲 04讲深入浅出索引(上)读书笔记 极客时间

    极客时间 Mysql实战45讲 04讲深入浅出索引 极客时间(上)读书笔记  笔记体悟 1.索引的作用:提高数据查询效率2.常见索引模型:哈希表.有序数组.搜索树3.哈希表:键 - 值(key - v ...

  4. MySQL的InnoDB索引原理详解

    摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇 ...

  5. MySQL的InnoDB索引原理详解 (转)

    摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...

  6. mysql优化之索引优化

    Posted by Money Talks on 2012/02/23 | 第一篇 序章第二篇 连接优化第三篇 索引优化第四篇 查询优化第五篇 到实战中去 索引优化 索引优化涉及到几个方面,包括了索引 ...

  7. MySQL实战 | 06/07 简单说说MySQL中的锁

    原文链接:MySQL实战 | 06/07 简单说说MySQL中的锁 本文思维导图:https://mubu.com/doc/AOa-5t-IsG 锁是计算机协调多个进程或纯线程并发访问某一资源的机制. ...

  8. MySQL实战 | 01-当执行一条 select 语句时,MySQL 到底做了啥?

    原文链接:当执行一条 select 语句时,MySQL 到底做了啥? 也许,你也跟我一样,在遇到数据库问题时,总时茫然失措,想重启解决问题,又怕导致数据丢失,更怕重启失败,影响业务. 就算重启成功了, ...

  9. 剖析Mysql的InnoDB索引

    摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...

随机推荐

  1. UVALive 4727 Jump(约瑟夫环,递推)

    分析: 如果问题是要求最后一个删除的数,重新编号为0到n-1,f[n]表示答案,那么f[n] = (f[n-1]+k)%n. 因为删掉下标k-1以后可以从下标k重新编号为0. 在这个问题只需要推出最后 ...

  2. Linux进程的虚拟存储器知识点

    http://blog.csdn.net/yxccc_914/article/details/52665713 用libreoffice画表真时有点蛋疼,效率很低.. 深入理解计算机系统->虚拟 ...

  3. 【BZOJ2243】[SDOI2011] 染色(树链剖分)

    点此看题面 大致题意: 有一棵\(n\)个节点的无根树和\(m\)个操作,且每个节点有一个颜色.操作有两种:一种是将两点树上路径之间所有点染成颜色\(c\),另一种是询问两点树上路径之间颜色段的数量. ...

  4. Matlab将多幅图片保存为mat

    %% 储存某目录所有的图片 pt = 'd:\imgs\'; ext = '*.jpg'; dis = dir([pt ext]); nms = {dis.name}; for k = 1:lengt ...

  5. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节

    第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...

  6. java实现单链表归并算法

    public class LinkMergeSort {static int number=0;public static void main(String[] args) {int[] a = {1 ...

  7. MitmProxy使用

    安装 tar -zxvf mitmproxy-3.0.1-linux.tar.gz sudo mv mitmproxy mitmdump mitmweb /usr/bin 详情 https://ger ...

  8. 打开POST传参的弹出窗口

    //穿件 function openPostPopWindow(url,param,target){ var $form = $("<form></form>&quo ...

  9. linux文件属性之时间戳及文件名属性知识

    7  8  9 三列是时间(默认是修改时间) modify 修改时间  -mtime  修改文件内容 change 改变时间 -ctime  文件属性改变 access 访问时间  -atime  访 ...

  10. Centos7多内核情况下修改默认启动内核方法

    1.1  进入grub.cfg配置文件存放目录/boot/grub2/并备份grub.cfg配置文件 [root@linux-node1 ~]# cd /boot/grub2/ [root@linux ...