MySQL InnoDB B-Tree索引使用Tips

这里主要讨论一下InnoDB B-Tree索引的使用,不提设计,只管使用。B-Tree索引主要作用于WHERE和ORDER BY子句。这里讨论的均在MySQL-Server-5.1.42测试

CREATE TABLE `friends` ( `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uid`bigint(20) UNSIGNED NOT NULL DEFAULT '0', `fuid` bigint(20) UNSIGNED NOT NULL DEFAULT'0', `fname` varchar(50) NOT NULL DEFAULT '', `fpicture` varchar(150) NOT NULL DEFAULT'', `fsex` tinyint(1) NOT NULL DEFAULT '0', `status` tinyint(1) NOT NULL DEFAULT '0',PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ALTER TABLE`friends` ADD INDEX uid_fuid (uid, fuid);

1.如果索引了多列,要遵守最左前缀法则。所谓最左前列,指的是查询从索引的最左前列开始,并且不跳过索引中的列。

第2条语句,从索引的第二列开始查找,使用索引失败,导致MySQL采用ALL访问策略,即全表查询.在开发中,应该尽量避免全表查询。
2.当MySQL一旦估计检查的行数可能会”太多”,范围查找优化将不会被使用。

第2条语句使用了全表查询,它与第1条语句唯一的区别在于需要检查的行数远远多于第1条语句。在应用中,可能不会碰到这么大的查询,但是应该避免这样的查 询出现: select uid from users where registered < 1295001384
3.索引列不应该作为表达式的一部分,即也不能在索引列上使用函数

第2和3条语句都有使用表达式,索引派不上用场。
4.尽量借用覆盖索引,减少select * from …语句使用

第1句Extra中使用了Using index表示使用了覆盖索引。第3句也使用了覆盖索引,虽然ID不在索引uid_fuid索引列中,但是InnoDB二次索引(second index)叶子页的值就是PK值,不同于MyISAM。Extra部分的Using index表示应用了索引,不要跟type中的index混淆。第2句没有使用覆盖索引,因为fsex不在索引中。
5.ORDER BY子句,尽量使用Index方式排序,避免使用FileSort方式排序
MySQL支持二种方式的排序,FileSort和Index,后者效率高,它指MySQL扫描索引本身完成排序。FileSort方式效率较低。ORDER BY满足以下情况,会使用Index方式排序:
            a)ORDER BY 语句使用索引最左前列。参见第1句
                    b)使用Where子句与Order BY子句条件列组合满足索引最左前列。参见第2句.
以下情况,会使用FileSort方式的查询

a)检查的行数过多,且没有使用覆盖索引。第3句,虽然跟第2句一样,order by使用了索引最左前列uid,但依然使用了filesort方式排序,因为status并不在索引中,所以没办法只扫描索引。
b)使用了不同的索引,MySQL每回只采用一个索引.第4句,order by出现二个索引,分别是uid_fuid和聚集索引(pk)
c)对索引列同时使用了ASC和DESC。 通过where语句将order by中索引列转为常量,则除外。第5句,和第6句在order by子句中,都出现了ASC和DESC排序,但是第5句却使用了filesort方式排序,是因为第6句where uid取出排序需要的数据,MySQL将其转为常量,它的ref列为const。
d)where语句与order by语句,使用了不同的索引。参见第7句。
e)where语句或者ORDER BY语句中索引列使用了表达式,包括函数表达式。参见第8,9句
f)where 语句与ORDER BY语句组合满足最左前缀,但where语句中使用了条件查询。查见第10句,虽然where与order by构成了索引最左有缀的条件,但是where子句中使用的是条件查询。
g)order by子句中加入了非索引列,且非索引列不在where子句中。
h)order by或者它与where组合没有满足索引最左前列。参见第11句和12句,where与order by组合,不满足索引最左前列. (uid, fsex)跳过了fuid
i)当使用left join,使用右边的表字段排序。参见第13句,尽管user.uid是pk,依然会使用filesort排序。



6.慎用left join语句,避免创建临时表 使用left join语句的时候,避免出现创建临时表。尽量不要用left join,分而治之。非要使用的时候,要询问自己是不是真要必须要使用。

7.高选择性索引列。 尽量使用高选择性的过引来过滤数据。高选择性指Cardinality/#T越接近1,选择性越高,其中Cardinality指表中索引列不重复值(行)的总数。PK和唯一索引,具有最高的选择性,即1。推荐可选性达到20%以上。

这里有二个索引可供使用,而MySQL选择PRIMARY,是因为它具有更高的选择性。
8.谨防where子句中的OR。where语句使用or,且没有使用覆盖索引,会进行全表扫描。应该尽量避免这样OR语句。尽量使用UNION代替OR

第1句虽然使用了索引,但是查行时间依然不可以恭维,mysql要检查的行很多,但是返回的行却很少.Extra中的using where表示需要通过where子句扔弃不需要的数据行。
9.LIMIT与覆盖索引 limit子句,使用覆盖索引时比没有使用覆盖索引会快很多

转自:http://my.oschina.net/longniao/blog/110384?fromerr=dKzaJdu1

MYSQL order by排序与索引关系总结的更多相关文章

  1. Mysql order by 排序 varchar 类型数据

    Mysql order by 排序 varchar 类型数据 varchar 类型字段排序,  会將数字当成字符串来处理.  排序规则一般是从左到右一位位来比较. +0之后 就转化成INT 类型排序 ...

  2. mysql order by 排序的问题

    参考博客http://blog.csdn.net/hollboy/article/details/13296601 mysql order by 的排序在今天时候遇到了问题 情景是:将排序的字段设置成 ...

  3. MySQL Order BY 排序过程

    MySQL 在进行 Order By 操作排序时,通常有两种排序方式: 全字段排序 Row_id 排序 MySQL 中每个线程在执行排序时,都会被分配一块区域 - sort buffer,它的大小通过 ...

  4. MYSQL order by 排序的一个小问题探究

    小问题发现: select * from `sql` where id=1 order by (select 1 union select 2) 正常返回结果 mysql> select * f ...

  5. mysql order by排序查询速度问题

    SELECT * FROM `assets_message` LEFT JOIN purchase_message ON assets_message.purchase_id = purchase_m ...

  6. MySQL如何利用索引优化ORDER BY排序语句

    MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通 ...

  7. MySQL如何利用索引优化ORDER BY排序语句 【转载】

    本文转载自:http://blog.csdn.net/ryb7899/article/details/5580624  .感谢相关作者. MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执 ...

  8. MySQL如何利用索引优化ORDER BY排序语

    MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通 ...

  9. MySql Order By 多个字段 排序规则

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xlxxcc/article/details/52250963 说在前面 突发奇想,想了解一下mysq ...

随机推荐

  1. luogu P1642 规划

    嘟嘟嘟 看到最后让求一个比值,应该得往01规划上去想.令x = ∑v[i] / ∑c[i],则x * ∑c[i] = ∑v[i], ∑(v[i] - x * c[i]) = 0. 于是可以二分x(注意 ...

  2. supervisord常见问题

    第一种: 你在没有修改配置文件之前就已经启动:~supervisord -c supervisord.conf 然后又去修改配置文件,想重新读取一下但是却出现了以下报错: Another progra ...

  3. 二十四、详述 IntelliJ IDEA 中自动生成 serialVersionUID 的方法

    当我们用 IntelliJ IDEA 编写类并实现 Serializable(序列化)接口的时候,可能会遇到这样一个问题,那就是: 无法自动生成serialVersionUID. 而serialVer ...

  4. PX4地面站QGroundControl在ubuntu下的安装

    1.引言 相信很多玩开源无人机的朋友手上都有一架无人机,而不是仅仅停留在理论的学习和程序的学习.放飞自己组装的无人机才是乐趣所在,那么这本文就介绍玩无人机必不可少的地面站软件qgroundcontro ...

  5. mpvue开发美团外卖点餐小程序

    mpvue-meituan mpvue-meituan 是一款使用mpvue开发的实战小程序项目,完全仿制美团官方外卖点餐小程序开发而成,项目的框架结构完全按照企业开发架构搭建而成.结合了原生小程序的 ...

  6. 一个hibernate中的异常:NonUniqueDiscoveredSqlAliasException

    在hibernate中用SQL查询返回的结果集中,列名或别名必须唯一,否则会报下面的错误.返回的结果集中,列名或别名可以没有,但只能有一列没有. //空别名重复的情况:org.hibernate.lo ...

  7. js中定时器使用方法经验总结

    前言,最近在做一个音频播放项目的时候,碰到播放时间精度的问题,捣鼓了几天,最终巧妙的运用定时器去降低了错误发生频率 正题,下面是对定时器的使用总结,如有错误之处,请读者加以纠正. 延迟执行(1次) s ...

  8. webpack安装与使用

    webpack: JavaScript 应用程序的静态模块打包器 安装webpack前需要搭建node环境: 1. 安装node.js(https://nodejs.org/en/), 安装完后会自动 ...

  9. vue调用豆瓣API加载图片403问题

    "豆瓣API是有请求次数限制的”,这会引发图片在加载的时候出现403问题,视图表现为“图片加载不出来”,控制台表现为报错403. 其实是豆瓣限制了图片的加载,我自己用了一个办法把图片缓存下来 ...

  10. 【Java】abstract,final,static,private,protected,public的区别

    [abstract]抽象的 1. abstract可以修饰类和成员方法,被abstract修饰的类称为抽象类,被abstract修饰成员方法叫抽象方法.抽象类不一定有抽象方法,但拥有抽象方法的类一定是 ...