MYSQL order by排序与索引关系总结

我们平常所说的索引,如果没有特别指明,都是指B+树结构组织的B-Tree索引。其中聚集索引,次要索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引。当然,除了B+树这种类型的索引之外,还有哈稀索引(hash index)等。

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子句,使用覆盖索引时比没有使用覆盖索引会快很多

时间: 2024-09-26 12:18:28

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

MySQL ORDER BY排序语句用法与优化

MySQL Order By语法  代码如下 复制代码  SELECT column_name(s) FROM table_name ORDER BY column_name 注意:SQL语句是"字母大小写不敏感"的语句(它不区分字母的大小写),即:"ORDER BY"和"order by"是一样的. MySQL Order By案例 下面的例子:从"Person"表中选取所有记录,并将"Age"列进行分类

php数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系_php技巧

krsort()定义和用法 krsort() 函数将数组按照键逆向排序,为数组值保留原来的键. 可选的第二个参数包含附加的排序标志. 若成功,则返回 TRUE,否则返回 FALSE. 语法 krsort(array,sorttype)参数 描述 array 必需.规定要排序的数组. sorttype 可选.规定如何排列数组的值.可能的值: SORT_REGULAR - 默认.以它们原来的类型进行处理(不改变类型). SORT_NUMERIC - 把值作为数字来处理 SORT_STRING - 把

php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系_php技巧

ksort()定义和用法 ksort() 函数按照键名对数组升序排序,为数组值保留原来的键. 可选的第二个参数包含附加的排序标志. 若成功,则返回 TRUE,否则返回 FALSE. 语法 ksort(array,sorttype)参数 描述 array 必需.规定要排序的数组. sorttype 可选.规定如何排列数组的值.可能的值: SORT_REGULAR - 默认.以它们原来的类型进行处理(不改变类型). SORT_NUMERIC - 把值作为数字来处理 SORT_STRING - 把值作

MySQL Order By索引优化

在一些情况下,MySQL可以直接使用索引来满足一个 ORDER BY 或 GROUP BY 子句而无需做额外的排序.尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了. 使用索引的MySQL Order By 下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: SELECT * FROM t1 ORDER BY key_part1,key_part2,...

MySQL Order By索引优化方法_Mysql

尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了. 使用索引的MySQL Order By 下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: 复制代码 代码如下: SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; SELECT * FROM t1 WHERE key_part1=constant ORD

php数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系_php技巧

asort() 定义和用法 asort() 函数对数组进行排序并保持索引关系.主要用于对那些单元顺序很重要的结合数组进行排序. 可选的第二个参数包含了附加的排序标识. 如果成功则返回 TRUE,否则返回 FALSE. 语法 asort(array,sorttype)参数 描述 array 必需.输入的数组. sorttype 可选.规定如何排列数组的值.可能的值: SORT_REGULAR - 默认.以它们原来的类型进行处理(不改变类型). SORT_NUMERIC - 把值作为数字来处理 SO

Oracle数据库中ORDER BY排序和查询按IN条件的顺序输出_oracle

ORDER BY非稳定的排序提一个问题: oracle在order by 排序时,是稳定排序算法吗? 发现用一个type进行排序后,做分页查询,第一页的数据和第二页的数据有重复 怀疑是order by 时,两次排列的顺序不一致 看到业务描述的问题可以得到的结论order by排序不稳定,还有第一个印象就是,type肯定是不唯一的,并且没有索引吧. 这里先科普下排序的稳定性,举个最简单的例子,1,2,3,1,4,5 排序 排序的结果是1,1,2,3,4,5,这时候观察这个1,如果第一个1还是排序前

MySQL order by性能优化方法实例

  这篇文章主要介绍了MySQL order by性能优化方法实例,本文讲解了MySQL中order by的原理和优化order by的三种方法,需要的朋友可以参考下 前言 工作过程中,各种业务需求在访问数据库的时候要求有order by排序.有时候不必要的或者不合理的排序操作很可能导致数据库系统崩溃.如何处理好order by排序呢?本文从原理以及优化层面介绍 order by . 一 MySQL中order by的原理 1 利用索引的有序性获取有序数据 当查询语句的 order BY 条件和

MySQL表设计优化与索引

  设计好MySql的索引可以让你的数据库飞起来,大大的提高数据库效率.设计MySql索引的时候有一下几点注意: 1.创建索引 对于查询占主要的应用来说,索引显得尤为重要.很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致.如果不加 索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下 降.但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么