MySQL从删库到跑路_高级(六)——索引
作者:天山老妖S
链接:http://blog.51cto.com/9291927
一、索引简介
1、索引简介
索引(Index)是帮助MySQL高效获取数据的数据结构。
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的。MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎支持HASH和BTREE索引。
2、索引的优点
A、提高数据检索效率,降低数据库的IO成本。
B、通过索引对数据进行排序,降低数据排序的成本降低了CPU的消耗。
C、大大加快数据的查询数据。
3、索引的缺点
A、创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加
B、索引也需要占空间,我们知道数据表中的数据也会有最大上线设置的,如果我们有大量的索引,索引文件可能会比数据文件更快达到上线值
C、当对表中的数据进行增加、删除、修改时,索引也需要动态的维护,降低了数据的维护速度。
4、索引的使用原则
A、主键自动建立唯一索引
B、频繁作为查询条件的字段应该创建索引
C、查询中与其他表关联的字段,外键关系建立索引
D、频繁更新的字段不适合建立索引,因为每次更新不单单是更新了记录还会更新索引
E、WHERE条件里用不到的字段不创建索引
F、单键/组合索引的选择问题,who?(在高并发下倾向创建组合索引)
G、查询中排序的字段,排序的字段若通过索引去访问将大大提高排序速度
H、查询中统计或者分组字段
不适合使用索引的场合:
A、对经常更新的表就避免对其进行过多的索引,对经常用于查询的字段应该创建索引。
B、数据量小的表最好不要使用索引,由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
C、在不同值少的列上不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。在一个不同值较多的列可以建立索引。
二、索引的分类
1、单列索引
单列索引只包含单个列,但一个表中可以有多个单列索引。
A、普通索引
普通索引允许在定义索引的列中插入重复值和空值。
B、唯一索引
索引列中的值必须是唯一的,但是允许为空值。
C、主键索引
主键索引是一种特殊的唯一索引,不允许有空值。
2、复合索引
在表中的多个字段组合上创建的索引,只有在查询条件中使用了组合的多个字段的左边字段时,索引才会被使用,使用复合索引时遵循最左前缀集合。
3、全文索引
全文索引,只有MyISAM存储引擎支持,只能在CHAR、VARCHAR、TEXT类型字段上使用全文索引。
全文索引主要用来查找文本中的关键字,而不是直接与索引中的值相比较。在数据量较大时候,先将数据放入一个没有全文索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。
4、空间索引
空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种:GEOMETRY、POINT、LINESTRING、POLYGON。
在创建空间索引时,使用SPATIAL关键字。
空间索引必须使用MyISAM存储引擎,并且空间索引的字段必须为非空。
三、索引的操作
1、索引的创建
创建表时创建索引的语法:
CREATE TABLE table_name[col_name data type] [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [index_name] (col_name[length]) [asc|desc]
在表上创建索引的语法:
ALTER TABLE tablename ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [indexname] (col_name) [ASC|DESC]; CREATE [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] indexname ON tablename(col_name[length]) [ASC|DESC];
uniquer|fulltext为何选参数,分别表示唯一索引、全文索引
col_name为需要创建索引的字段列,该列必须从数据表中该定义的多个列中选择
index_name指定索引的名称,为可选参数,如果不指定,默认col_name为索引值
length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度
asc或desc指定升序或降序的索引值存储
在创建索引时如果不指定索引名,默认使用字段名索引名。
2、普通索引的创建
直接创建索引
CREATE INDEX index_name ON tablename(column(length))
修改表结构
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
创建表时指定索引
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,INDEX index_name(col_name)
);
3、唯一索引的创建
索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
直接创建唯一索引
CREATE UNIQUE INDEX indexName ON tablename(column(length))
修改表结构
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,UNIQUE INDEX index_name(col_name)
);
4、主键索引的创建
修改表结构
ALTER TABLE table_name ADD PRIMARY KEY(col_name)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
PRIMARY KEY(col_name)
);
5、复合索引的创建
直接创建复合索引
CREATE INDEX indexName ON tablename(col_name1,col_name2)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,INDEX index_name(col_name1,col_name2)
);
6、全文索引的创建
直接创建全文索引
CREATE FULLTEXT INDEX indexName ON tablename(col_name)
修改表结构
ALTER TABLE table_name ADD FULLTEXT INDEX indexName(col_name)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
FULLTEXT INDEX index_name(col_name)
);
在使用全文索引时,需要借助MATCH AGAINST操作,而不是一般的WHERE语句加LIKE。全文索引的限制比较多,比如只能使用MyISAM存储引擎,比如只能在CHAR、VARCHAR、TEXT上设置全文索引。比如索引的关键字默认至少要4个字符,比如搜索的关键字太短就会被忽略掉。
SELECT * FROM tablename WHERE MATCH(col_name) AGAINST('pattern');
col_name为全文索引列,'pattern'为匹配的字符串
7、索引的删除
DROP INDEX [indexName] ON tablename;
ALTER TABLE tablename DROP INDEX indexname;
8、索引信息的查看
SHOW INDEX FROM table_name;
9、索引的注意事项
A、索引不会包含有null值的列
在数据库设计时不要让字段的默认值为null。
B、使用短索引
C、索引列排序
因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
D、like语句操作
一般情况下不推荐使用like操作,如果非使用不可。like"%aaa%不会使用索引而like"aaa%"可以使用索引。
E、不要在列上进行运算
在索引列上进行运算将导致索引失效而进行全表扫描例如
SELECT * FROM table_name WHERE YEAR(column_name)<2017;
F、不使用not in和<>操作
四、索引查询速度比较
1、插入记录
create procedure addStudent(in num int)
begin
declare i int;
set i=1;delete from TStudent;while num>=i doinsert TStudent values (
LPAD(convert(i,char(10)),10,'0'),
CreateName(), if(ceil(rand()*10)%2=0,'男','女'),
RPAD(convert(ceil(rand()*1000000000000000000),char(18)),18,'0'),
Concat(convert(ceil(rand()*10)+1980,char(4)),'-',LPAD(convert(ceil(rand()*12),char(2)),2,'0'),'-',LPAD(convert(ceil(rand()*28),char(2)),2,'0')),
Concat(PINYIN(sname),'@hotmail.com'),
case ceil(rand()*3) when 1 then '网络与网站开发' when 2 then 'JAVA' ELSE 'NET' END,
NOW()
);
set i=i+1;
end while;select * from TStudent;
end
修改addStuent存储过程,插入500000条记录
call addStudent(500000);
SQL语句查询xxx号cardID以12345开头的学生。
select * from TStudent where cardID like '12345%'
花费时间为1.27秒
2、给XXX列添加索引
alter table TStudnet add index cardidIndex(cardID);
SQL查询xxx号cardID以12345开头的学生。
select * from TStudent where cardID like'12345%'
花费时间31毫秒。
3、查看索引占用的磁盘空间
schoolDB数据库索引占用的磁盘空间。
SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB')
AS 'Total Index Size' FROM information_schema.TABLESWHERE table_schema LIKE 'schoolDB';
查看schoolDB数据库数据占用的磁盘空间。
SELECT CONCAT(ROUND(SUM(data_length)/(1024*1024), 2), ' MB')
AS 'Total Data Size' FROM information_schema.TABLES WHERE table_schema LIKE 'schoolDB';
4、查看SQL语句执行计划
EXPLAIN可以查看SQL查询语句的查询计划,使用索引还是全表扫描,key显示使用的索引。
explain select * from TStudent where cardid like '12345%' \G;
id:SELECT识别符,即SELECT的查询序列号,一条语句中,select是第几次出现。
select_type:所使用的SELECT查询类型,SIMPLE表示为简单的SELECT,不实用UNION或子查询。其他取值,PRIMARY:最外面的SELECT在拥有子查询时,就会出现两个以上的SELECT。UNION:union(两张表连接)中的第二个或后面的select语句 SUBQUERY:在子查询中,第二SELECT。
table:数据表的名字。按被读取的先后顺序倒序排列。
type:指定本数据表和其他数据表之间的关联关系,表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录做联合。ref用于连接程序使用键的最左前缀或者键不是primary key或unique索引的情况。取值有system、const、eq_ref、index和AII。
possible_keys:MySQL在搜索数据记录时可以选用的各个索引
key:实际选用的索引
key_len:显示MySQL使用索引的长度(使用的索引个数),当key字段的值为null时,索引的长度就是null。
ref:给出关联关系中另一个数据表中数据列的名字。
rows:MySQL在执行查询时预计会从数据表里读出的数据行的个数。
extra:提供与关联操作有关的信息。
五、覆盖索引
1、覆盖索引
一个包含查询所需的字段的索引称为覆盖索引(covering index)。MySQL只需要通过索引就可以返回查询所需要的数据,而不必在查到索引之后进行回表操作,减少IO,提供效率。
通过EXPLAIN查看SQL语句的执行计划时,说明SQL查询使用覆盖索引。
2、使用覆盖索引的SQL语句
Tstudent表cardID列创建了索引,SQL语句查找的列是cardID,就会使用cardID索引进行查找,不需要扫描表的页。
explain select sname from TStudent where sname like '刘%';
执行结果Extra出现using index,说明是使用覆盖索引查找。
3、使用覆盖索引实现order by排序
在MySQL中的ORDER BY有两种排序实现方式:
A、利用有序索引获取有序数据
B、文件排序
使用EXPLAIN分析SQL查询时,利用有序索引获取有序数据显示Using index。而文件排序显示Using filesort。
explain select email from TStudent order by email;
email列没有索引,SQL语句的查询计划可以看到Extra是using filesort,说明是将结果在内存中排序,需要额外时间开销。
给Email列添加索引后,
alter table TStudent add index emailIndex(email);explain select email from TStudent order by email;
再次执行,可以看到Extra列是Using index,说明使用索引排序,没有额外时间开销。
喜欢的小伙伴们可以搜索我们个人的微信公众号“程序员的成长之路”点击关注或扫描下方二维码
MySQL从删库到跑路_高级(六)——索引的更多相关文章
- MySQL从删库到跑路_高级(七)——事务和锁
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.事务简介 1.事务简介 事务(Transaction)是指作为单个逻辑工作单元执行的一系列操作. 2.事物的特效 ...
- MySQL从删库到跑路_高级(五)——触发器
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.触发器简介 1.触发器简介 触发器是和表关联的特殊的存储过程,可以再插入,删除或修改表中的数据时触发执行,比数据 ...
- MySQL从删库到跑路_高级(四)——存储过程
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.存储过程简介 1.存储过程简介 存储过程是一组具有特定功能的SQl语句集组成的可编程的函数,经编译创建并保存在数 ...
- MySQL从删库到跑路_高级(二)——自定义函数
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.自定义函数简介 自定义函数(user-defined function UDF)是一种对MySQL扩展的途径,其 ...
- MySQL从删库到跑路_高级(一)——数据完整性
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.数据完整性简介 1.数据完整性简介 数据冗余是指数据库中存在一些重复的数据,数据完整性是指数据库中的数据能够正确 ...
- MySQL从删库到跑路_高级(三)——视图
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.视图简介 1.视图简介 视图是由SELECT查询语句所定义的一个虚拟表,是查看数据的一种非常有效的方式.视图包含 ...
- MySQL从删库到跑路(三)——SQL语言
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.SQL语言简介 1.SQL语言简介 SQL是结构化查询语言(Structured Query Language) ...
- MySQL从删库到跑路(五)——SQL查询
作者:天山老妖S 链接:http://blog.51cto.com/9291927 1.查询所有字段 在SELECT语句中使用星号“”通配符查询所有字段在SELECT语句中指定所有字段select f ...
- MySQL从删库到跑路(一)——MySQL数据库简介
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.MySQL简介 1.MySQL简介 MySQL是一个轻量级关系型数据库管理系统,由瑞典MySQL AB公司开发, ...
随机推荐
- VC++ 学习笔记3 获取编辑框字符串
边界框添加字符串比较简单 可以直接在对话框的空间上面点击右键添加变量,变量类型为CString 在此取名为m_NUM 直接使用m_NUM就是编辑框的CString, 举例: 在messagebox显 ...
- Android - dhroid 开发框架
extends:http://www.eoeandroid.com/thread-326973-1-1.html 开源中国地址:http://www.oschina.net/p/dhroid 开源项目 ...
- SDWebImage第三方库使用注意的一些问题
1.利用"UIImageView+WebCache.h"加载图片数据 例如: UIImage *placeHolderImg = [UIImage imageNamed:@&quo ...
- Linux wc
命令参数: -c 统计字节数. -l 统计行数. -m 统计字符数.这个标志不能与 -c 标志一起使用. -w 统计字数.一个字被定义为由空白.跳格或换行字符分隔的字符串. -L 打印最长行的长度. ...
- 7.24 IO多路复用和协程代码笔记
1. 复习 # !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/23 11:49 # !@Author TrueNew ...
- 1.5神经网络可视化显示(matplotlib)
神经网络训练+可视化显示 #添加隐层的神经网络结构+可视化显示 import tensorflow as tf def add_layer(inputs,in_size,out_size,activa ...
- (转载)准确率(accuracy),精确率(Precision),召回率(Recall)和综合评价指标(F1-Measure )-绝对让你完全搞懂这些概念
自然语言处理(ML),机器学习(NLP),信息检索(IR)等领域,评估(evaluation)是一个必要的工作,而其评价指标往往有如下几点:准确率(accuracy),精确率(Precision),召 ...
- CNN中的卷积理解和实例
卷积操作是使用一个二维卷积核在在批处理的图片中进行扫描,具体的操作是在每一张图片上采用合适的窗口大小在图片的每一个通道上进行扫描. 权衡因素:在不同的通道和不同的卷积核之间进行权衡 在tensorfl ...
- 最长上升子序列 OpenJ_Bailian - 2757 dp模板
第一种是用以前状态更新当前状态(人人为我) 第二种是用当前状态更新以后状态(我为人人) 都是n^2代码: 对于人人为我的更新方法,可以用数据结构储存“人人”对其进行线性\二分优化. ; int a[m ...
- 企业证书安装App
通过苹果自带的浏览器访问:itms-services:///?action=download-manifest&url=https://www.xxxx.com:xxx/xxxx/xxx.pl ...