MySQL的索引类型和左前缀索引
1.索引类型:
1.1B-tree索引:
注:名叫btree索引,大的方面看,都用的是平衡树,但具体的实现上,各引擎稍有不同,比如,严格的说,NDB引擎,使用的是T-tree,但是在MyISAM,Innodb中,默认的使用的是B-tree索引
但我们抽象一下---B-tree系统,可以理解成为“排好序的快速查找结构”
1.2hash索引
在memory表中,默认的是hash索引,hash的理论查询时间复杂度为O(1)
那为啥hash的查找如此的搞笑,为什么都不用hash索引?
答:1.hash函数计算后的结果,是随机的,如果是在磁盘上放置数据,以主键id为例,那么随着id的增长,id对应的行,在磁盘上随机的放置。
2.无法对范围查询进行优化。
3.无法利用前缀索引 比如 在btree中, field列的值“hellopworld”,并加索引查询 xx=helloword,自然可以利用索引, xx=hello,也可以利用索引. (左前缀索引) 因
为hash(‘helloword’),和hash(‘hello’),两者的关系仍为随机
4.排序无法进行优化。
5.必须得回行。就是说,通过索引拿到的数据位置,必须回到表中取出数据。
2.btree索引的常见误区:
2.1在where条件常用的列上加上索引。
例如:where cat_id=3 and price>100;// 查询第3个栏目,100元以上的商品。
误区:cat_id 和price上都加索引
错误:只能用上cat_id或者是price索引,因为都是独立的索引,同时只能用上1个
2.2 在多列上建立索引后,查询那个列,索引都将会发挥作用。
误区:在多列索引上,索引发挥作用,需要满足左前缀需求。
以index(a,b,c)为例:
语句 |
索引是否发挥作用 |
where a=3 | 是,只是用了a列的索引 |
Where a=3 and b=5 |
是,使用了a,b列 |
Where a=3 and b=5 and c=4 |
是,使用了abc |
Where b=3 or where c=4 |
否 |
Where a=3 and c=4 |
a列能发挥索引,c不能 |
Where a=3 and b>10 and c=7 |
A能利用,b能利用, C不能利用 |
同上,where a=3 and b like ‘xxxx%’ and c=7 |
A能用,B能用,C不能用 |
为便于理解, 假设ABC各10米长的木板, 河面宽30米.
全值索引是则木板长10米,
Like,左前缀及范围查询, 则木板长6米,
自己拼接一下,能否过河对岸,就知道索引能否利用上.
如上例中, where a=3 and b>10, and c=7,
A板长10米,A列索引发挥作用
A板正常接B板, B板索引发挥作用
B板短了,接不到C板, C列的索引不发挥作用.
假设某个表有一个联合索引(c1,c2,c3,c4)一下——只能使用该联合索引的c1,c2,c3部分
A where c1=x and c2=x and c4>x and c3=x
B where c1=x and c2=x and c4=x order by c3
C where c1=x and c4= x group by c3,c2
D where c1=x and c5=x order by c2,c3
E where c1=x and c2=x and c5=? order by c2,c3
create table t4 (
c1 tinyint(1) not null default 0,
c2 tinyint(1) not null default 0,
c3 tinyint(1) not null default 0,
c4 tinyint(1) not null default 0,
c5 tinyint(1) not null default 0,
index c1234(c1,c2,c3,c4)
);
insert into t4 values (1,3,5,6,7),(2,3,9,8,3),(4,3,2,7,5);
对于A:
c1=x and c2=x and c4>x and c3=x <==等价==> c1=x and c2=x and c3=x and c4>x
因此 c1,c2,c3,c4都能用上. 如下:
mysql> explain select * from t4 where c1=1 and c2=2 and c4>3 and c3=3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: range
possible_keys: c1234
key: c1234
key_len: 4 #可以看出c1,c2,c3,c4索引都用上
对于B: select * from t4 where c1=1 and c2=2 and c4=3 order by c3
c1 ,c2索引用上了,在c2用到索引的基础上,c3是排好序的,因此不用额外排序.
而c4没发挥作用.
mysql> explain select * from t4 where c1=1 and c2=2 and c4=3 order by c3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 2
ref: const,const
rows: 1
Extra: Using where
1 row in set (0.00 sec) mysql> explain select * from t4 where c1=1 and c2=2 and c4=3 order by c5 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 2
ref: const,const
rows: 1
Extra: Using where; Using filesort
1 row in set (0.00 sec)
对于 C: 只用到c1索引,因为group by c3,c2的顺序无法利用c2,c3索引
mysql> explain select * from t4 where c1=1 and c4=2 group by c3,c2 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 1 #只用到c1,因为先用c3后用c2分组,导致c2,c3索引没发挥作用
ref: const
rows: 1
Extra: Using where; Using temporary; Using filesort
1 row in set (0.00 sec) mysql> explain select * from t4 where c1=1 and c4=2 group by c2,c3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 1
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
D语句: C1确定的基础上,c2是有序的,C2之下C3是有序的,因此c2,c3发挥的排序的作用.因此,没用到filesort
mysql> explain select * from t4 where c1=1 and c5=2 order by c2,c3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 1
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
E: 这一句等价与 elect * from t4 where c1=1 and c2=3 and c5=2 order by c3; 因为c2的值既是固定的,参与排序时并不考虑
mysql> explain select * from t4 where c1=1 and c2=3 and c5=2 order by c2,c3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
type: ref
possible_keys: c1234
key: c1234
key_len: 2
ref: const,const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
上面就是一个比较经典的左前缀的匹配案例,因此我们在工作中应该在经常使用的列上加索引。
MySQL的索引类型和左前缀索引的更多相关文章
- mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)
没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...
- mysql索引之四:复合索引之最左前缀原理,索引选择性,索引优化策略之前缀索引
高效使用索引的首要条件是知道什么样的查询会使用到索引,这个问题和B+Tree中的“最左前缀原理”有关,下面通过例子说明最左前缀原理. 一.最左前缀索引 这里先说一下联合索引的概念.MySQL中的索引可 ...
- mysql多列索引和最左前缀
数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度.索引优化是数据库优化的最重要手段. 如果查询语句使用 ...
- MySQL 的索引和最左前缀原则
这两天看<构建高性能Web站点>这本书,感觉写的真是不错,很多实际项目中会碰到的问题都有所提及,今天看到一个最左前缀原则,以前也听说过,不过一直没搞明白,今天查了下. 通过实例理解单列索引 ...
- MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序
MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序 What's Index ? 索引就是帮助RDBMS高效获取数据的数据结构. 索引可以让我们避免一行一行进行全表扫描.它的 ...
- 我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知
面试官: 我看你的简历上写着精通MySQL,问你个简单的问题,MySQL联合索引有什么特性? 心想,这还不简单,这不是问到我手心里了吗? 听我给你背一遍八股文! 我: MySQL联合索引遵循最左前缀匹 ...
- Mysql联合索引的最左前缀原则以及b+tree
软件版本mysql5.7 根据官网的文档 https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html 查询条件要符合最左原 ...
- 关于MySQL索引的最左前缀匹配原则原理说明说明
假设有2个这样的SQL SELECT * FROM table WHERE a = 1 AND c = 3; // c不走索引 SELECT * FROM table WHERE a = 1 AND ...
- MySQL的前缀索引及Oracle的类似实现
MySQL有一个很有意思的索引类型,叫做前缀索引,它可以给某个文本字段的前面部分单独做索引,从而降低索引的大小. 其实,Oracle也有类似的实现,对于文本,它可以通过substr的函数索引,实现同样 ...
随机推荐
- 使用Ajax实现的批量删除操作(C#)
今天做了一个简单的批量删除操作,虽然简单,但是很多问题出现,终究还是技术不够熟练. 现在在这里跟大家分享一下.仅供学习... 1.在前台获取用户点击的信息id,把这里id封装到一个数组里面:(rows ...
- C#获取json字符串指定的值
Newtonsoft.Json在json和对象之间转化是一个非常强大的工具. 对象转化json字符串 Newtonsoft.Json.JsonConvert.SerializeObject() jso ...
- <<Numerical Analysis>>笔记
2ed, by Timothy Sauer DEFINITION 1.3A solution is correct within p decimal places if the error is l ...
- bug--常见的bug总结:
新手总结的开发中所遇到错误及解决办法,如有不对,欢迎指正,如有更好的解决办法,也请不吝赐教. 一.dialog.show()引起的android.view.WindowManager$BadToken ...
- Git 版本库添加空目录方法
直接在版本库工作目录下创建空目录后,使用git status查看,发现空目录没有被版本库识别. 正确的添加空目录的方法: 在空目录下创建.gitkeep文件:touch .gitkeep 然后重新执行 ...
- 拥抱高效、拥抱 Bugtags 之来自用户的声音 2
小编按:这是一篇 Bugtags 用户来稿,主要是介绍了使用 Bugtags 前后对测试及解决 Bug 所带来的变化,感谢单车娱乐 App 工程师 - 李斌同学对 Bugtags 的信赖和支持.小编在 ...
- 怎么打开sql server 数据库日志文件
To Open Log File Viewer, 1. Expand Server Node > 2. Expand SQL Server Agent > 3. Expand Jobs & ...
- java获取文件夹下文件名
public static String [] getFileName(String path) { File file = new File(path); String [] fileName = ...
- Laravel学习笔记(三)数据库 数据库迁移
该章节内容翻译自<Database Migration using Laravel>,一切版权为原作者. 原作者:Stable Host, LLC 翻译作者:Bowen Huang 正文: ...
- LeetCode 168. Excel Sheet Column Title
Given a positive integer, return its corresponding column title as appear in an Excel sheet. -> A ...