MySQL|索引应用

能够先看下这篇理论介绍:html


MySQL|索引背后
mysql


01
算法

MySQL的几种KEYsql


PRIMARY KEY 有两个做用,一是约束做用(constraint),用来规范一个存储主键和惟一性,但同时也在此key上创建了一个主键索引;每一个表都应该有一个主键,而且每一个表只能有一个主键。数据库


UNIQUE  KEY 与  PRIMARY KEY类似,只不过每一个表能够有多个主键。微信


FOREIGN KEY 也是在这个key上创建一个index ,以下所示:   FOREIGN KEY(emp_no)  REFERENCES employees (emp_no)    ON DELETE CASCADE,代表此表的emp_no引用的是employees表的emp_no,同时ON DELETE CASCADE指明一旦删除employees的某emp_no的记录,相应也会在这个表中删除这条记录。机器学习



02
编辑器

employees示例库学习


看这个概念前,先介绍一个实例库。flex


导入MySql的employees库,下载地址:

https://dev.mysql.com/doc/employee/en/employees-installation.html


解压缩后,找到 employees.sql,注意最后几行的source ***.dump,在往数据库中导入时候,最后指定它的绝对路径,而后导入。


这个库包括6张表,关系以下:





03

索引index


看下titles表里面的索引,

SHOW INDEX FROM employees.titles;


titles表的主索引为<emp_no, title, from_date>


titles表的行数为

443307



04

全列匹配


查看严格按照索引组合的查询解释:


EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10002' AND title='Staff' AND from_date='1996-08-03';



很明显,当按照索引中全部列进行精确匹配(这里精确匹配指“=”或“IN”匹配)时,索引能够被用到。



05

最左前缀匹配


EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10002';



条件所组成的最左前缀。上面的查询从分析结果看用到了PRIMARY索引,可是key_len为4,说明只用到了索引的第一列前缀。




06

缺失最左前缀匹配


EXPLAIN SELECT * FROM employees.titles WHERE title='Staff' AND from_date='1996-08-03';


因为不是最左前缀,这样的查询显然用不到索引。



07

范围查询


EXPLAIN SELECT * FROM employees.titles WHERE emp_no<'10010'


最左前缀的范围列能够用到索引,范围索引只能有一个。



08

每张表都得建索引?


答案是否认的。由于添加索引须要付出相应的代价,索引文件自己要消耗存储空间,同时索引会加剧插入、删除和修改记录时的负担。通常两种状况下不建议建索引。


第一种状况是表记录比较少,例如一两千条甚至只有几百条记录的表,不必建索引,让查询作全表扫描就行了。


另外一种索引的选择性较低时不须要创建索引。所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值:

Index Selectivity = Cardinality / #T


以下所示为employees的cardinality:




09

根据选择性创建索引


SELECT count(DISTINCT(concat(first_name, last_name)))/count(*) AS Selectivity FROM employees.employees;


获得的选择值为:0.9313


可是这样的索引组合可能致使键值过长。


取last_name的前4个字符:


SELECT count(DISTINCT(concat(first_name, left(last_name, 4))))/count(*) AS Selectivity FROM employees.employees;


获得的选择值为:0.900


已经不错了。


没有添加组合索引前的查询:

SELECT * FROM employees.employees WHERE first_name='Eric' AND last_name='Anido'


耗时:0.609s


添加组合索引:

ALTER TABLE employees.employees ADD INDEX `first_name_last_name4` (first_name, last_name(4));


再次查询,耗时:0.0009s


前缀索引兼顾索引大小和查询速度,可是其缺点是不能用于ORDER BY和GROUP BY操做,也不能用于Covering index。



参考文章:

http://blog.codinglabs.org/articles/theory-of-mysql-index.html


以上,索引的应用实例,若是有疏漏,请指导!


算法channel会有系统地,认真地推送:基础算法/机器学习/深度学习/spark/tensorflow等全栈内容。期待您的参与!QQ交流群: 646901659 或进入公众号界面->导读系列下,进入微信讨论群。

本文分享自微信公众号 - Python与算法社区(alg-channel)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索