mysql 多列索引的生效规则
mysql中 myisam,innodb默认使用的是 Btree索引,至于btree的数据结构是怎样的都不重要,
只需要知道结果,既然是索引那这个数据结构最后是排好序;就像新华字典他的目录就是按照a,b,c..这样排好序的;
所以你在找东西的时候才快,比如你找 “中” 这个字的解释,你肯定就会定位到目录的 z 开头部分;
组合索引可以这样理解,比如(a,b,c),abc都是排好序的,在任意一段a的下面b都是排好序的,任何一段b下面c都是排好序的;

组合索引的生效原则是 从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用;
比如
where a=3 and b=45 and c=5 .... 这种三个索引顺序使用中间没有断点,全部发挥作用;
where a=3 and c=5... 这种情况下b就是断点,a发挥了效果,c没有效果
where b=3 and c=4... 这种情况下a就是断点,在a后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;
where b=45 and a=3 and c=5 .... 这个跟第一个一样,全部发挥作用,abc只要用上了就行,跟写的顺序无关
(a,b,c) 三个列上加了联合索引(是联合索引 不是在每个列上单独加索引)
还需注意, (a,b,c)多列索引和 (a,c,b)是不一样的,看上面的图也看得出来关系顺序是不一样的;
分析几个实际例子来加强理解;
分析句子中使用的索引情况
() select * from mytable where a= and b= and c=;
abc三个索引都在where条件里面用到了,而且都发挥了作用
() select * from mytable where c= and b= and a=;
这条语句列出来只想说明 mysql没有那么笨,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
() select * from mytable where a= and c=;
a用到索引,b没有用,所以c是没有用到索引效果的
() select * from mytable where a= and b> and c=;
a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
() select * from mytable where b= and c=;
因为a索引没有使用,所以这里 bc都没有用上索引效果
() select * from mytable where a> and b= and c=;
a用到了 b没有使用,c没有使用
() select * from mytable where a= order by b;
a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的
() select * from mytable where a= order by c;
a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
() select * from mytable where b= order by a;
b没有用到索引,排序中a也没有发挥索引效果
补充一个:
快速生成1000W测试数据库;
创建测试表:
create table user (
id int(10) not null auto_increment,
uname varchar(20) ,
regtime char(30) ,
age int(11) ,
primary key (id)
)
engine=myisam default charset=utf8 collate=utf8_general_ci ,
auto_increment=1 ;
编写存储过程:
delimiter $$
SET AUTOCOMMIT = 0$$ create procedure test()
begin
declare v_cnt decimal (10) default 0 ;
dd:loop
insert into user values
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50),
(null,rand()*10,now(),rand()*50);
commit;
set v_cnt = v_cnt+10 ;
if v_cnt = 10000000 then leave dd;
end if;
end loop dd ;
end;$$ delimiter ;
调用存储过程:
call test();
mysql 多列索引的生效规则的更多相关文章
- mysql 多列索引的生效规则,生成1000w数据的存储过程
https://www.cnblogs.com/codeAB/p/6387148.html
- mysql多列索引和最左前缀
数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度.索引优化是数据库优化的最重要手段. 如果查询语句使用 ...
- Mysql的列索引和多列索引(联合索引)
转自:http://blog.chinaunix.net/uid-29305839-id-4257512.html 创建一个多列索引:CREATE TABLE test ( id ...
- 正确理解Mysql的列索引和多列索引
MySQL数据库提供两种类型的索引,如果没正确设置,索引的利用效率会大打折扣却完全不知问题出在这. CREATE TABLE test ( id INT NOT NULL, last_ ...
- mysql多列索引优化
“把Where条件里面的列都建上索引”,这种说法其实是非常错误的! 这样一个查询,假设actor_id与film_id都单独建立索引 SELECT film_id , actor_id FROM sa ...
- MySQL 多列索引优化小记
MySQL 5.6.30 问题背景 由于爬虫抓取的数据不断增多,这两天在不断对数据库以及查询语句进行优化,其中一个表结构如下: CREATE TABLE `newspaper_article` ( ` ...
- Mysql多列索引实践
在网上看到: 定义:最左前缀原则指的的是在sql where 子句中一些条件或表达式中出现的列的顺序要保持和多索引的一致或以多列索引顺序出现,只要 出现非顺序出现.断层都无法利用到多列索引. 该博文有 ...
- Mysql多列索引经典案例
一个经典的多列索引案例,如题: 假设某个表有一个联合索引(c1,c2,c3,c4)一下--只能使用该联合索引的 c1,c2,c3 部分 Awhere c1=x and c2=x and c4>x ...
- mysql优化之索引建立的规则
索引经常使用的数据结构为B+树.结构例如以下 如上图,是一颗b+树,关于b+树的定义能够參见B+树,这里仅仅说一些重点.浅蓝色的块我们称之为一个磁盘块,能够看到每一个磁盘块包括几个数据项(深蓝色所看到 ...
随机推荐
- 【动态规划】洛谷P1004方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- Python Tornado篇
Tornado既是一个web server,也是web framework.而它作为web server 采用的是asynchronous IO的网络模型,这是一种很高效的模型. Tornado 和现 ...
- 【转载】MySQL · 性能优化· InnoDB buffer pool flush策略漫谈
背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数个内存块加上一组控制结构体对象组成.内存块的个数取决于buffer pool inst ...
- for/in 循环遍历对象的属性
for/in 语句循环遍历对象的属性. js中获取key得到某对象中相对应的value的方法:obj.key js中根据动态key得到某对象中相对应的value的方法有二: 一.var key = & ...
- 关于ODP.NET连接数监控及相应的windbg分析提示
1.关于ODP.NET的Windows计数器问题 使用微软的缺省驱动时,可以通过windows性能监视器很方便的监控数据库连接数,选择.NET Data Provider for Oracle/Sql ...
- python函数定义
刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函 ...
- 基于Windows下python环境变量配置
方法和Java环境变量配置是一样的,不懂的请移步这里 虽然这样说,还是唠唠叨叨几句吧QAQ 默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使 ...
- sql server 2008 r2 数据库操作时提示 9002错误“事物日志已满”问题
事务日志截断 若要避免数据库的事务日志被填满,例行备份至关重要.在简单恢复模式下,备份了数据库后会自动截断日志,而在完整恢复模式下,只有备份了事务日志后方才截断日志.但是,截断过程有时也可能发生延迟. ...
- [学习OpenCV攻略][003[初试牛刀——显示图片]
cvLoadImage(路径) 加载指定路径的图片到内存 cvNamedWindow("窗口名称", 属性) 创建窗口,窗口名称用来被其他函数引用,属性:0表示窗口大小不变,CV_ ...
- 利用nginx 虚拟主机、请求转发实现不同端口web访问
一个服务器上挂一个网站实在是有点浪费:一个服务器上可以放多个网站:可以开启nginx的虚拟主机功能:利用访问的路径或者域名不同访问不同的文件夹:例如: 1.一台服务器上放多个网站使用nginx的配置文 ...