为什么索引有mysql 最左前缀原则则

联合索引有一个最左前缀原则,所以建立联合索引的时候,这个联合索引的字段顺序非常重要
下面写了例子说明这个:
CREATE TABLE `test_myisam` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`conference_id` varchar(200) NOT NULL,
`account` varchar(100) DEFAULT NULL,
`status` int(2) DEFAULT NULL COMMENT '0:invite,
1:cancel_invite,
2:decline,
3:connect',
`duration` bigint(20) unsigned DEFAULT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=myisam AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
以上表结构,我想通过三列进行查询 account ,status,create_time进行查询统计。
如何建立索引?
因为我们有可能按照acccount单独统计,或者按照account status,或者是account,status,create_time进行统计,如何建立索引???
下面是建立索引前后的对比600万数据
如何生成:执行如下脚本,account和日期不同还有status不同,分别生成一百万。
PROCEDURE `add_data_myisam_cp_27`()
declare v_rows int(10) default 1000000;
declare v_count int(10) default 0;
id_loop:LOOP
insert into test_myisam values(null,round(rand()*),'cloudp',round(rand()*3),round(rand()*100000),' 00:00:22');
set v_count= v_count + 1;
if v_count&v_rows then
end loop id_
测试结果利用建立的索引性能提高了三倍:
MariaDB [prf]& select count(1) from test_myisam where account='cloudp' and status =3 and date(create_time)='';
+----------+
1 row in set (1.28 sec)
MariaDB [prf]& create index as_index on test_myisam(account,status,create_time);
Query OK, 6000006 rows affected (31.60 sec)
Records: 6000006
Duplicates: 0
Warnings: 0
MariaDB [prf]& select count(1) from test_myisam where account='cloudp' and status =3 and date(create_time)='';
+----------+
1 row in set (0.42 sec)
MariaDB [prf]& explain select count(1) from test_myisam where account='cloudp' and status =3 and date(create_time)='';
+------+-------------+-------------+------+---------------+----------+---------+-------------+--------+--------------------------+
1 row in set (0.00 sec)
从1.28秒下降到0.42秒
但是这个date(create_time)会对每一列都会转换后对比,这里会比较消耗性能;
如何利用上索引??
MariaDB [prf]& explain select count(1) from test_myisam where account='cloudp' and status =3 and date(create_time)='';
+------+-------------+-------------+------+---------------+----------+---------+-------------+--------+--------------------------+
1 row in set (0.00 sec)
MariaDB [prf]& select count(1) from test_myisam where account='cloudp' and status =3 and create_time
between '' and '';
+----------+
1 row in set (0.15 sec)
MariaDB [prf]& explain select count(1) from test_myisam where account='cloudp' and status =3 and create_time
between '' and '';
+------+-------------+-------------+-------+---------------+----------+---------+------+--------+--------------------------+
1 row in set (0.00 sec)
如上效率又提高了三倍,是因为扫描的数据行数减少了,最后一个create_time如果不用索引需要扫描52016行,如果使用了索引扫描174152行,命中的行数为:167400行,命中率非常高了。
这里有个疑问:
如果按照天进行统计,create_time作为联合索引的第一列,如何使用上这个索引呢????
至今没有想清楚,如果这一列是date类型可以直接用上索引,如果在oracle中可以date(create_time)建立函数式索引。但是mysql貌似不支持函数式索引。
一个解决方式是: create_time定义为 date类型,在每一列存入的时候,通过触发器自动把这一行修改为date类型。
如果有好的注意欢迎留言探讨,目前没有好的方式加上create_time,可以从业务上解决,就是每天的统计计算完成以后,直接把数据推到历史表中,统计结果单独存放。
本文已收录于以下专栏:
相关文章推荐
1. 索引建立的原则
用于索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。
仅仅出现在SELECT关键字后面的输出数据列列表中的数据列...
这两天看《构建高性能Web站点》这本书,感觉写的真是不错,很多实际项目中会碰到的问题都有所提及,今天看到一个最左前缀原则,以前也听说过,不过一直没搞明白,今天查了下。
通过实例理解单列索引、多...
1. 索引建立的原则
用于索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。
仅仅出现在SELECT关键字后面的输出数据列列表中的数据列...
问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响...
昨天做一个企业的笔试题,对数据库这块了解很浅,所以还是记录一下吧。B-Tree 索引和 Hash 索引的对比
对于 B-tree 和 hash 数据结构的理解能够有助于预测不同存储引擎下使用不同索引...
http://blog.csdn.net/SkySuperWL/article/details/
昨天做一个企业的笔试题,对数据库这块了解很浅,所以还是记录一下吧。
一、什么是索引? 
  索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要...
在 5.6 以及之后的版本被解除了!
这是你的表结构,有三个字段,分别是id,name,cid
CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` ...
表结构和索引列假设数据库中表是这样的:
我们只考虑一张表employees.titles:
索引是(emp_no,title,from_date)SHOW INDEX FROM employees...
他的最新文章
讲师:AI100
讲师:谢梁
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)mysql索引最左匹配原则的理解? - 知乎141被浏览16980分享邀请回答/mysql-index.html简单来说,就是MySQL采用b+树原理查询,每次查询复合字段从左到右的属性。在执行2的第一行代码时,查询值只有cid,而你的name_cid_index的首字段是name,所以MySQL找不到该索引。在执行2的第二行时,情况发生变化,你的查询值变成了(cid,name),mysql会一直向右匹配直到遇到范围查询(&、&、between、like)就停止匹配,因而会查询到name字段。希望能对你有所帮助。5添加评论分享收藏感谢收起2016年1月 其他数据库开发大版内专家分月排行榜第二2014年12月 其他数据库开发大版内专家分月排行榜第二2014年11月 其他数据库开发大版内专家分月排行榜第二2014年5月 其他数据库开发大版内专家分月排行榜第二
2014年3月 其他数据库开发大版内专家分月排行榜第三
2017年1月 其他数据库开发大版内专家分月排行榜第二2014年8月 其他数据库开发大版内专家分月排行榜第二2014年2月 其他数据库开发大版内专家分月排行榜第二2014年1月 其他数据库开发大版内专家分月排行榜第二2013年12月 其他数据库开发大版内专家分月排行榜第二2013年10月 其他数据库开发大版内专家分月排行榜第二2013年8月 其他数据库开发大版内专家分月排行榜第二2013年5月 其他数据库开发大版内专家分月排行榜第二2013年1月 其他数据库开发大版内专家分月排行榜第二2012年8月 其他数据库开发大版内专家分月排行榜第二2012年5月 其他数据库开发大版内专家分月排行榜第二2012年4月 其他数据库开发大版内专家分月排行榜第二2012年1月 其他数据库开发大版内专家分月排行榜第二
2017年9月 其他数据库开发大版内专家分月排行榜第三2017年7月 其他数据库开发大版内专家分月排行榜第三2017年5月 其他数据库开发大版内专家分月排行榜第三2017年3月 其他数据库开发大版内专家分月排行榜第三2016年12月 其他数据库开发大版内专家分月排行榜第三2014年11月 其他数据库开发大版内专家分月排行榜第三2014年7月 其他数据库开发大版内专家分月排行榜第三2014年6月 其他数据库开发大版内专家分月排行榜第三2014年5月 其他数据库开发大版内专家分月排行榜第三2013年7月 其他数据库开发大版内专家分月排行榜第三2013年3月 其他数据库开发大版内专家分月排行榜第三2012年7月 其他数据库开发大版内专家分月排行榜第三2012年6月 其他数据库开发大版内专家分月排行榜第三2011年12月 其他数据库开发大版内专家分月排行榜第三
2010年 总版技术专家分年内排行榜第二
2009年 总版技术专家分年内排行榜第三
本帖子已过去太久远了,不再提供回复功能。}

我要回帖

更多关于 最左前缀匹配原则 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信