Mysql优化之创建高性能索引(二)
1.索引的优点
索引可以让服务器快速地定位到表的指定位置。总结下来有三大优点:
- 索引大大减少了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机I/O变为顺序I/O
2.高性能的索引策略
独立的列
我们通常会看到一些查询不当地使用索引,或者使得Mysql无法使用已有的索引,比如:
SELECT ID FROM B WHERE ID + = ;
Mysql无法解析这个方程式,我们应该养成简化where条件的习惯,下面是另一个常见错误:
SELECT A FROM B TO_DAYS(CURRENT_DATE) - TO_DAYS(date) <= 10;
前缀索引和索引选择性
有时候需要索引很长的字符列,这会让索引变得大且慢。通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。但这样会降低索引的选择性。索引的选择性指不重复的索引值和数据表的记录总数的比值,比值越高表示选择性越好。
一般来说,对于BLOB、TEXT或者很长的VARCHAR类型的列来说,必须使用前缀索引,因为Mysql不允许索引这些列的完整长度,那么如何选取合适的前缀长度又不失选择性呢,我们来做个实验:
//创建一个只含有字符串的数据表
CREATE TABLE `demo` (
name varchar() not null
); //往里面插入1000000条乱序字符串
CALL `insert_demo`();
下面我们观察下数据表:
select count(distinct name) / count(*) from demo;
select count(distinct LEFT(name,7)) / count(*) from demo;
select count(distinct LEFT(name,9)) / count(*) from demo;
select count(distinct LEFT(name,11)) / count(*) from demo;
select count(distinct LEFT(name,12)) / count(*) from demo;
select count(distinct LEFT(name,13)) / count(*) from demo;
可以看到取前缀长度为11,12,13时,选择性已跟第一条基准非常接近,取其中任一长度都可以。只看平均选择性是不够的,还需要看数据分布均不均匀。
//比如取的是11,可对比取11个长度与取总长度的数据分布对比,大家可以自行实验
SELECT COUNT(*) as ant, LEFT(name, ) as pref FROM demo GROUP BY pref ORDER BY cnt DESC LIMIT ;//对比
SELECT COUNT(*) as ant, name as pref FROM demo GROUP BY pref ORDER BY cnt DESC LIMIT ;//基准
前缀索引是一种能使索引更小,更快的方法,但也有个缺点,就是无法使用前缀索引进行覆盖扫描。一个常见的场景就是对很长的ID字段进行前缀索引。
多列索引
上一节讨论过索引顺序问题,比如以下情况:
//把where条件里面的列都建上索引
CREATE TABLE t (
c1 INT,
c2 INT,
c3 INT,
KEY(c1),
KEY(c2),
KEY(c3)
);
在复杂场景下,这些索引并非最好,比最优的索引还要差几个数量级。单列索引并不能提高Mysql的查询性能,常见策略有“索引合并”,下面我们来讨论一下
以下面的查询为例:
SELECT * FROM payment WHERE staff_id = AND customer_id = ;
这里应该创建一个(staff_id,customer_id)索引还是应该颠倒以下顺序?我们先看看各个WHERE条件分支对于的数据基数有多大:
根据经验法则,应该将索引列customer_id放在前面,因为其对应的数据量更小,我们再来看看对customer_id的条件值,对应的staff_id列的选择性如何:
这里需要注意的是,查询结果非常依赖于选定的具体值,如果按上述优化可能对其他条件的查询不公平,服务器的整体性能也不见得会变好,如果是从pt-query=digest这样的工具提取的“最差”查询,那么再按上述办法选定索引顺序才会变得更加高效。
customer_id的选择性更高,因此customer_id作为索引第一列。
最后,尽管关于选择性和基数的经验法则值得去研究和分析,但一定要记住别忘了where子句的排序、分组和范围条件等其他因素,这些因素可能对查询的性能找出非常大的影响。
Mysql优化之创建高性能索引(二)的更多相关文章
- Mysql优化之创建高性能索引(一)
1.索引基础 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.但是不恰当的索引随着数据量的增加,也会使整个数据库的性能下降. 举个例子: ; 如果在id上建立索引 ...
- Mysql优化之创建高性能索引(三)
聚蔟索引 聚蔟索引并不是一种单独的索引类型,而是一种数据存储方式.Innodb的聚蔟索引在同一结构保存了B-Tree索引和数据行. 当表有聚蔟索引时,它的数据行实际上存放在索引的叶子页中.下图展示了聚 ...
- php面试专题---16、MySQL创建高性能索引考点
php面试专题---16.MySQL创建高性能索引考点 一.总结 一句话总结: 注意:只写精品 1.索引的基础? 类似书籍的目录:索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录 ...
- mysql笔记02 创建高性能的索引
创建高性能的索引 1. 索引(在MySQL中也叫做"键(key)")是存储引擎用于快速找到记录的一种数据结构. 2. 索引可以包含一个或多个列的值.如果索引包含多个列,那么列的顺序 ...
- MySQL 创建高性能索引
索引是存储引擎用于快速找到记录的一种数据结构.除了加速查找,索引在其他方面也有一些有用的属性.索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较 ...
- MySQL创建高性能索引
参考<高性能MySQL>第3版 1 索引基础 1.1 索引作用 在MySQL中,查找数据时先在索引中找到对应的值,然后根据匹配的索引记录找到对应的数据行,假如要运行下面查询语句: 如果在u ...
- 《高性能MySQL》——第五章创建高性能索引
1.创建索引基本语法格 在MySQL中,在已经存在的表上,可以通过ALTER TABLE语句直接为表上的一个或几个字段创建索引.基本语法格式如下: ALTER TABLE 表名 ADD [UNIQUE ...
- PHP面试 MySQL创建高性能索引考点
MySQL索引 MySQL索引的基础和类型 索引的基础:索引类似于书籍的目录,要想找到一本书的某个特定篇章,需要查找书的目录,定位对应的页码 存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的 ...
- [MySQL-笔记]创建高性能索引
索引,MySQL中也叫“键”,是存储引擎中用于快速找到记录的一种数据结构,具体的工作方式就像书本中的索引一样,但是具体的实现方式会有差别. 一.索引分类 B-Tree索引: 优点: MyISAM中,索 ...
随机推荐
- OpenCV——肤色检测
一.RGB color space 检测代码如下: void SkinRGB(IplImage* src,IplImage* dst) { //RGB颜色空间 //均匀照明:R>95,G> ...
- C++语法报错收集
1. error C2864: "OuterClass::m_outerInt": 只有静态常量整型数据成员才可以在类中初始化 class OuterClass { public: ...
- 一个有趣的问题——MySQL中varchar的最大长度
明明维护了一个1k的最小堆,可是输出到MySQL里却只有九百多行数据. 查log,发现这么一段内容: stderr logs com.mysql.jdbc.MysqlDataTruncation: D ...
- CSS3动画之无缝滚动
与js的无缝滚动类似,整个承载图片的盒子移动,克隆一组图片放置最后,当一组图片播放结束后将盒子定位在有一组图片宽度的左侧 HTML结构: <div class="box"&g ...
- Swift是一个提供RESTful HTTP接口的对象存储系统
Swift是一个提供RESTful HTTP接口的对象存储系统,最初起源于Rackspace的Cloud Files,目的是为了提供一个和AWS S3竞争的服务. Swift于2010年开源,是Ope ...
- jQuery之Jcrop
头像裁剪是一个经常用到的功能,实现原理也较为简单,就是在本地选择好所需裁剪图片的坐标,将坐标发送到服务器,由服务器执行图片裁剪操作. jQuery插件Jcrop提供了强大的图片裁剪坐标选择插件.一下来 ...
- javascript调试
今天,发现了一个之前从未注意的角落,相信能够大大提高自己写JS的速度.能够迅速发现错误. 例如,今天的加班中调试一个js错误发现的一个例子. 1.Google浏览器报的错 以上是google浏览器报的 ...
- javascript之DOM操作
一.document.getElementById() 根据Id获取元素节点 <div id="div1"> <p id="p1"> ...
- jQuery中的选择器《思维导图》
学习jQuery的课程中,我对jQuery中的选择器有了更深的认识,它的简洁写法,完美的兼容性,可靠的处理机制,都让我们省了很多事, 下面是我在学习过程中对jQuery选择器写的思维导图(全屏查看:& ...
- SQL数据转移
方法一:如果想把数据库A中的表Table1中的数据复制到数据库B中的表Table2中,也就是要预先建立Table2,可以使用一下语句: use B goinsert into Table2 selec ...