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优化之创建高性能索引(二)的更多相关文章

  1. Mysql优化之创建高性能索引(一)

    1.索引基础 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.但是不恰当的索引随着数据量的增加,也会使整个数据库的性能下降. 举个例子: ; 如果在id上建立索引 ...

  2. Mysql优化之创建高性能索引(三)

    聚蔟索引 聚蔟索引并不是一种单独的索引类型,而是一种数据存储方式.Innodb的聚蔟索引在同一结构保存了B-Tree索引和数据行. 当表有聚蔟索引时,它的数据行实际上存放在索引的叶子页中.下图展示了聚 ...

  3. php面试专题---16、MySQL创建高性能索引考点

    php面试专题---16.MySQL创建高性能索引考点 一.总结 一句话总结: 注意:只写精品 1.索引的基础? 类似书籍的目录:索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录 ...

  4. mysql笔记02 创建高性能的索引

    创建高性能的索引 1. 索引(在MySQL中也叫做"键(key)")是存储引擎用于快速找到记录的一种数据结构. 2. 索引可以包含一个或多个列的值.如果索引包含多个列,那么列的顺序 ...

  5. MySQL 创建高性能索引

    索引是存储引擎用于快速找到记录的一种数据结构.除了加速查找,索引在其他方面也有一些有用的属性.索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较 ...

  6. MySQL创建高性能索引

    参考<高性能MySQL>第3版 1 索引基础 1.1 索引作用 在MySQL中,查找数据时先在索引中找到对应的值,然后根据匹配的索引记录找到对应的数据行,假如要运行下面查询语句: 如果在u ...

  7. 《高性能MySQL》——第五章创建高性能索引

    1.创建索引基本语法格 在MySQL中,在已经存在的表上,可以通过ALTER TABLE语句直接为表上的一个或几个字段创建索引.基本语法格式如下: ALTER TABLE 表名 ADD [UNIQUE ...

  8. PHP面试 MySQL创建高性能索引考点

    MySQL索引 MySQL索引的基础和类型 索引的基础:索引类似于书籍的目录,要想找到一本书的某个特定篇章,需要查找书的目录,定位对应的页码 存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的 ...

  9. [MySQL-笔记]创建高性能索引

    索引,MySQL中也叫“键”,是存储引擎中用于快速找到记录的一种数据结构,具体的工作方式就像书本中的索引一样,但是具体的实现方式会有差别. 一.索引分类 B-Tree索引: 优点: MyISAM中,索 ...

随机推荐

  1. TCP/UDP网络编程的基础知识与基本示例(windows和Linux)

    一.TCP编程的一般步骤 服务器端: 1.创建一个socket,用函数socket() 2.绑定IP地址.端口等信息到socket上,用函数bind() 3.开启监听,用函数listen() 4.接收 ...

  2. Draw2d中的布局管理器Layout比较

    最近在研究Eclipse中的GEF开发,在跟着GEF-whole-upload教程做一个GEF应用程序的例子时,发现Figure上的控件无法显示,谷歌了很久也没找到解决方案,最后终于发现是Layout ...

  3. setInterval && setTimeout || 定时器

    来自w3school的解释 定时器setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停地调用函数,直到 clearInterva ...

  4. jquery判断表单提交是否为空

    <input type="text" value="" name="toPage"> 判断该表单是否为空 var p = $(& ...

  5. img元素高度多出来的几像素

    HTML: <div class="test"><img src="body2.jpg" alt=""></d ...

  6. grep;egrep;fgrep

    -1 使用场景:搜索定位内容并输出(所在行) -2 三者区别: --1 grep  默认支持普通正则 --2 egrep 默认支持扩展正则 等同于 grep -E --3 fgrep 速度最快,不支持 ...

  7. ubuntu下安装fiddler

    因为工作中需要用到fiddler工具  现在工作环境迁移到ubuntu14 下  发现fiddler只支持windows网上也有很多推荐 号称可以代替fiddler   但因为功能使用上比较习惯  并 ...

  8. 从Qt4到Qt5的,主要的进化有三(对于QtWidget的精简和优化会很有限)

    从Qt4到Qt5的,主要的进化有三:1 语言的进化,原来是基于C++(qtwidget)和XML(.ui),现在添加了QML(QtQuick)+JS(v8)的架构.2 绘图系统的进化,原先基于QPai ...

  9. C# ToString()和Convert.ToString()的区别

    一.一般用法说明 ToString()是Object的扩展方法,所以都有ToString()方法;而Convert.ToString(param)(其中param参数的数据类型可以是各种基本数据类型, ...

  10. 关于WPF中承载 ArcGIS控件。

    原文 http://www.cnblogs.com/zoe-j/archive/2011/05/18/2050208.html 之前就做过WPF的应用,之前承载的MapGIS的二次开发控件,今天写一下 ...