什么是索引?
举个例子:新华字典,有目录,有正文内容。索引就相当于目录,正文内容就相当于数据。
索引有什么用?
索引用于快速查找在某列中有一特定值的行。
一条查询语句,如果没有索引,将对全表进行扫描。
如果所有的数据页面都不在内存中,则需要从硬盘上读取这些页面,从而产生大量的I/O,每次I/O都会消耗一定时间。
最终,总的查询时间,会大的惊人。
使用索引
若此时查询列有个索引,MYSQL 就能快速定位到具体位置,找出相关列,将指定数据页面读入内存,I/O 就会大大降低。
以字典为例,查找字母为 Z 开头的某个单词,先通过索引定位 Z 开头的单词的起始位置,从这里开始查询,从而节省了大量的时间。
一次查询能使用多个索引吗?
一次查询只能使用一个索引。
哪些常见情况不能用索引?
like “%xxx”
not in , !=
对列进行函数运算的情况(如 where avg(age) = “20”)
如何分析是否正确用到索引?
explain select ...
联合索引的问题
假设,你有一个三列联合的索引:(col1, col2, col3)。
那么你将拥有三种索引使用方式:
(col1)
(col1, col2)
(col1, col2, col3)
上述说的就是最左前缀 – leftmost prefix。
So,当你有多列查询需求时,你可以考虑建一个合适的联合索引。
关于like查询
like 的参数不以非通配符 % 开头的字符常量,就能使用索引。
SELECT * FROM tbl_name WHERE key_col LIKE 'something%'; //匹配以something开头的字符串
SELECT * FROM tbl_name WHERE key_col LIKE '%something%'; //不使用索引
SELECT * FROM tbl_name WHERE key_col LIKE 'something'; //精确匹配,等效于 “ = ” 运算符
假如,你在看一本成语词典,目录是按成语拼音顺序建立。
查询需求是:你想找以 “一” 字开头的成语(“一%”),和你想找包含一字的成语(“%一%”)。
你觉得哪个会更快呢?
索引越多越好?
大多数情况下,索引都能大幅度提高查询效率。
数据的增、删、改操作都需要维护索引,索引一多,意味着维护成本高了。
更多的索引需要更多的存储空间。比如:20页的书,有15页的目录?这就不合理了。
小表建索引,往往适得其反。比如:读个2页的宣传手册,你还先去找目录?
什么样的字段不适合建索引?
更新非常频繁的列
列的值唯一性太小,比如性别,Enum 类型的字段等
太长的列