`

sql order by与索引之间的关系(where条件出现字段才有效)

    博客分类:
  • sql
 
阅读更多
ORDER BY 通常会有两种实现方法,一个是利用有序索引自动实现,也就是说利用有序索引的有序性就不再另做排序操作了。另一个是把结果选好之后再排序。

用有序索引这种,当然是最快的,不过有一些限制条件,来看下面的测试。

测试数据:student表有两个字段id ,sid ,id是主键。一共有20W条记录,id从1到200000,sid也是从1到200000的数据。

第一种情况 :

order by的字段不在where条件也不在select中

select sid from zhuyuehua.student where sid < 50000 order by id;



第二种情况 :

order by的字段不在where条件但在select中。

select id,sid from zhuyuehua.student where sid < 50000 order by id;



第三种情况 :

order by的字段在where条件但不在select中。

select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id;



第四种情况 :

order by的字段在where条件但不在select中。倒序排列

select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id desc;



测试结果:

order by的字段不在where条件不在select中     有排序操作

order by的字段不在where条件但在select中     有排序操作

order by的字段在where条件但不在select中     无排序操作

order by的字段在where条件但不在select中(倒序)     无排序操作

结论:

当order by 字段出现在where条件中时,才会利用索引而无需排序操作。其他情况,order by不会出现排序操作。

分析:

为什么只有order by 字段出现在where条件中时,才会利用该字段的索引而避免排序。这要说到数据库如何取到我们需要的数据了。

一条SQL实际上可以分为三步。

1.得到数据

2.处理数据

3.返回处理后的数据

比如上面的这条语句select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id desc

第一步:根据where条件和统计信息生成执行计划,得到数据。

第二步:将得到的数据排序。

当执行处理数据(order by)时,数据库会先查看第一步的执行计划,看order by 的字段是否在执行计划中利用了索引。如果是,则可以利用索引顺序而直接取得已经排好序的数据。如果不是,则排序操作。

第三步:返回排序后的数据。

另外:

上面的5万的数据sort只用了25ms,也许大家觉得sort不怎么占用资源。可是,由于上面的表的数据是有序的,所以排序花费的时间较少。如果 是个比较无序的表,sort时间就会增加很多了。另外排序操作一般都是在内存里进行的,对于数据库来说是一种CPU的消耗,由于现在CPU的性能增强,对 于普通的几十条或上百条记录排序对系统的影响也不会很大。但是当你的记录集增加到上百万条以上时,你需要注意是否一定要这么做了,大记录集排序不仅增加了 CPU开销,而且可能会由于内存不足发生硬盘排序的现象,当发生硬盘排序时性能会急剧下降。

注:ORACLE或者DB2都有一个空间来供SORT操作使用(上面所说的内存排序),如ORACLE中是用户全局区(UGA),里面有SORT_AREA_SIZE等参数的设置。如果当排序的数据量大时,就会出现排序溢出(硬盘排序),这时的性能就会降低很多了。

总结:

当order by 中的字段出现在where条件中时,才会利用索引而不排序,更准确的说,order by 中的字段在执行计划中利用了索引时,不用排序操作。

这个结论不仅对order by有效,对其他需要排序的操作也有效。比如group by 、union 、distinct等。
  • 大小: 16 KB
  • 大小: 16 KB
  • 大小: 20.6 KB
  • 大小: 21 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    SQL-ORDER BY 多字段排序(升序、降序)

    在实际操作中,`ORDER BY`常与其他SQL子句(如`GROUP BY`, `JOIN`等)结合使用,以满足复杂的数据查询需求。通过理解并熟练掌握`ORDER BY`多字段排序,可以更好地对数据库中的数据进行管理和分析。 总之,`ORDER BY...

    76当我们在SQL里进行分组的时候,如何才能使用索引?.pdf

    在设计表的索引时,应该考虑到未来SQL查询的模式,包括哪些字段将用于过滤(WHERE子句)、排序(ORDER BY)以及分组(GROUP BY)。通过合理设计两到三个索引,可以覆盖大多数的查询需求,确保常用的SQL语句都能利用...

    数据库面试题索引sql优化

    - 为经常出现在WHERE子句中的列创建索引。 - 对于频繁使用的JOIN操作中的关联列建立索引。 - 考虑使用复合索引来同时优化多个列的查询性能。 2. **减少全表扫描:** - 使用WHERE子句过滤记录,避免不必要的全表...

    SQL常见命令及使用方法

    - `SELECT * FROM 表名 WHERE 字段名 LIKE '%字段值%' ORDER BY 字段名 [DESC]`:与上面类似,但是这里使用了`LIKE`操作符来实现模糊匹配。 - 示例:`SELECT * FROM Customers WHERE FirstName LIKE '%a%' ORDER ...

    MySQL Order By索引优化方法

    比如,当`ORDER BY`的字段完全包含在索引中,或者与`WHERE`子句中的条件匹配时,MySQL可以高效地利用索引。以下是一些能够使用索引优化`ORDER BY`的例子: 1. 查询按索引完全顺序排列的数据: ```sql SELECT * ...

    sql优化、索引的建立和运用以及多表连接建索引的拙劣见解

    - 如果必须使用`ORDER BY`,尝试将排序字段设置为索引的一部分。 5. **使用NOT EXISTS代替NOT IN**: - `NOT IN`在某些情况下会导致索引失效。 - 示例:`SELECT * FROM A WHERE A.id NOT IN (SELECT B.id FROM B)...

    SQL语法、索引优化

    3. **使用WHERE子句**:在WHERE子句中使用索引字段,避免在这些字段上使用不等运算符(如、NOT IN、BETWEEN等)和函数,因为这可能导致索引无法被有效利用。 4. **分组和排序**:GROUP BY和ORDER BY操作可能会导致...

    SQL Server索引重建手册

    这两种方法可以有效帮助数据库管理员识别出那些碎片率较高的索引,根据`avg_fragmentation_in_percent`字段,如果该值大于50%,通常建议对该索引进行重建。 ### 索引重建方式 在确认需要重建的索引后,接下来是...

    sql索引、试图简介

    - **分组和排序**:在使用GROUP BY和ORDER BY子句时,索引可以减少分组和排序的时间。 - **优化隐藏器**:通过索引,查询处理器可以更好地优化SQL语句,提高系统性能。 - **缺点** - **创建和维护成本**:随着...

    sql语句全解 vf 数据库

    SELECT [字段名列表] FROM [表名] [WHERE 条件] [GROUP BY 字段名] [HAVING 条件] [ORDER BY 字段名] [LIMIT 条件] 其中: * SELECT 说明要查询的数据 * FROM 说明要查询的数据来自那个或那些表 * WHERE 说明查询...

    用SQL语句表与字段的基本操作、数据库备份等

    SQL(Structured Query Language)是用于管理和处理关系型数据库的标准语言。在本篇内容中,我们将深入探讨如何使用SQL进行表和字段的基本操作,包括添加、删除和修改字段,以及数据库对象的重命名和查询。这些操作...

    SQL索引一步到位1

    - 经常用于排序(ORDER BY)、分组(GROUP BY)或过滤(WHERE子句)的列应该创建索引。 - 数据列的更新频率高或值变化大的列不适合建立索引,因为这会增加索引维护的成本。 - 文本、图像和位类型的数据列以及重复值...

    【MySQL】经验:索引使用场景

    一、适合用索引的场景 ...这里要注意,order by的字段出现在where条件中才能使用索引,否则索引失效。 5、查询中的统计、分组字段 group by和union也属于需要排序的操作,这里也要注意字段出现在whe

    presto sql 与mysql sql 对比.pdf

    例如,在 MySQL SQL 中,`where` 条件中的字符串类型可以隐式转换为数字类型,但这可能会造成索引不起效和非预期的结果。 聚合函数 Presto SQL 和 MySQL SQL 都支持聚合函数,如 `count()`、`sum()`、`avg()` 等。...

    SQLServer索引调优实践

    SELECT * FROM Table1 WHERE Data1 = 2 ORDER BY DTAt DESC; ``` 假设执行后得到的结果如下: ``` Table 'Table1'. Scan count 1, logical reads 911, physical reads 0, read-ahead reads 0, lob logical reads 0...

    覆盖索引及案例

    通常来说,这些字段包括`WHERE`子句中的条件字段、`SELECT`列表中的返回字段以及`ORDER BY`或`DISTINCT`后的字段。 2. **选择合适的字段顺序**: - 字段的顺序对于索引的性能至关重要。通常将过滤条件字段作为索引...

    索引和sql语句优化

    - **建立索引**:在WHERE和ORDER BY子句中涉及的列上建立索引。 - **使用合适的索引类型**:例如,使用唯一索引或者主键索引来加速查询。 **2. 避免NULL值判断** 在WHERE子句中直接对字段进行NULL值判断(如 `...

    2022年关系数据库查询语言-SQL.ppt

    SELECT &lt;字段列表&gt; FROM &lt;数据源&gt; WHERE &lt;条件&gt; ORDER BY &lt;字段列表&gt; 例如: SELECT 学号, 成绩 FROM 成绩表 WHERE 课程ID=“001” AND 成绩&gt;60 ORDER BY 成绩 DESC; ### 带 FROM、GROUP BY 和 HAVING 子句的 ...

    SQLServer索引设计和调优技巧大全.pdf

    选择那些经常出现在JOIN、WHERE、ORDER BY、GROUP BY等SQL子句中的字段作为索引字段。 - 对于小表,尤其是查找表,使用索引可能反而降低性能,直接扫描表可能更快。 4. **多字段索引**: - 多字段索引适用于那些...

    数据库SQL优化大总结之 百万级数据库优化方案.pdf

    1. 在where及order by涉及的列上建立索引,以避免全表扫描。 二、数据库SQL优化之避免NULL值 2. 尽量避免在where子句中对字段进行NULL值判断,以免引擎放弃使用索引而进行全表扫描。 三、数据库SQL优化之避免!=和...

Global site tag (gtag.js) - Google Analytics