|10分钟掌握MySQL的索引查询优化技巧( 三 )
- SELECT * from people where Age = 2
- SELECT * from people where NAME like ‘%B’
- SELECT * from people where age = 2
- SELECT * from people where NAME = ‘ABC’ AND number = 3
- SELECT * from people where NAME like ‘B%’ and age = 22
如果表中有一列存储较长字符串 , 假设名字为URL , 在此列上创建的索引比较大 , 有个办法可以缓解:创建URL字符串的数字哈希值的索引 。 再新建一个字段 , 比如叫做URL_CRC , 专门放置URL的哈希值 , 然后给这个字段创建索引 , 查询时这样写:
select * from t where URL_CRC = 387695885 and URL = 'www.baidu.com'
如果数据量比较多 , 为防止哈希冲突 , 可自定义哈希函数 , 或用MD5函数返回值的一部分作为哈希值:
SELECT CONV(RIGHT(MD5('www.baidu.com'),16), 16, 10)
前缀索引
如果字符串列存储的数据较长 , 创建的索引也很大 , 这时可以使用前缀索引 , 即:只针对字符串前几个字符做索引 , 这样可以缩短索引的大小 , 不过 , 显然 , 此类索引在执行order by和group by时不起作用 。
创建前缀索引时选择前缀长度很重要 , 在不破坏原来数据分布的情况下尽可能选择较短的前缀 。 举个例子 , 如果如果大部分字符串是以”abc”开头 , 那么如果限定前缀索引长度为4 , 索引值会包含太多的重复的”abcX” 。
多列索引
上面提到的“People”上创建的索引即为多列索引 , 多列索引往往比多个单列索引更好 。
- 对多个索引进行and查询时 , 应该创建多列索引 , 而不是多个单列索引
- 可以试试这样写的效果:
多列索引的顺序很重要 , 通常 , 不考虑排序和分组查询时 , 应该把选择性(选择性是指某表索引列不同数据的个数/总行数 。 选择性高意味着重复数据少)大的列放到前面 。 但也有例外 , 如果能确认某些查询是频繁执行的 , 则应该优先照顾这些查询的选择性 , 比如 , 如果上面的People表中Name的选择性大于Age , 查询语句应该这样写:
select * from people where name = 'xxx' and age = xx
Name列放了索引中的左侧比较合适 , 但是如果某个SQL执行的评率最高 , 比如
select * from people where name = 'xxx' and age = 20
当age=20的记录在数据库中非常少时 , 反而把age放到索引列的左端效率更高 。 把age放了索引左端可能对其它age不等于20的查询来说不公平 , 如果不能确定age=20是最非常频繁的查询条件 , 还是要综合考虑 , 把name放了左侧合适 。
聚簇索引
聚簇索引是一种数据存储结构 , InnoDB在主键的索引的叶子节点中直接保存了数据行 , 而不是像二级索引那样只是保存了索引列的值和所指向行的主键值 。 由于这个特性 , 一个表只能有一个聚簇索引 。 如果一个表没有定义主键也没有定义具有唯一索引的列 , 那么InnoDB会生成一个隐藏列 , 并且在此列设为聚簇索引列 。
覆盖索引
简单地说 , 某些查询只需要查询索引列 , 那么就不用再根据索引B树节点记录的主键ID进行二次查询了 。
重复索引和冗余索引
如果重复在某列创建索引 , 并不会带来任何好处 , 只有坏处 , 应该尽量避免 。 比如给主键创建唯一索引和普通索引就是多于的 , 因为InnoDB的主键默认就是聚簇索引了 。
推荐阅读
- 数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?
- 小记|MySQL集群数据问题修复小记
- 通路|直播10分钟卖10万元,这家新通路联合仓是怎么做到的?
- 环球网|直播10分钟卖10万元,这家新通路联合仓是怎么做到的?
- |MySQL使用基础,这么用就对了
- |直播10分钟卖10万,这家新通路联合仓是怎么做到的?
- 科学|一个人10分钟能吞多少热狗?
- 5G|百瓦级闪充,满电10分钟!氮化镓概念欲展翅乘风?
- 手机|华为自研手机处理器或成绝唱?要想硬气还得掌握核心科技
- 手机|只有掌握了芯片技术,才能在移动市场占据先机,五大品牌你识几个