ORDER BY子句的性能取决于参与排序操作的数据量的大小。
排序操作会在数据筛选完以后,对筛选出的结果集进行排序。因此,对于需要排序的查询,应将排序操作控制在结果集数据量尽量小的查询中,避免对大批量数据进行排序操作,这样可以避免不必要的CPU资源消耗,并且,当排序操作超过可以分配的内存大小时,会把排序的中间数据存放在Tempdb数据库中,这将增加I/O操作,导致语句的性能大大下降。
在不得不对大量数据进行排序操作的情况下,适当地创建一些索引对排序操作会有一定的帮助,例如代码清单3-3中的语句。
代码清单3-3 排序语句
SELECT sod.OrderQty, sod.ProductID FROM Sales.SalesOrderDetail AS sod WHERE sod.ProductID=870 ORDER BY sod.OrderQty DESC
对大批量数据进行查询时,其执行计划如图3-3所示,在只有聚集索引的情况下,从执行计划中可以看出,SQL Server首先会对SalesOrderDetail表进行一次表扫描,找出所需要的数据;然后对检索出来的数据进行一次Sort操作(操作中的主要开销都在聚集索引扫描中,大约占了87%,这里先不讨论该SQL语句的性能)。针对这个Sort操作,创建如下索引,代码如清单3-4所示。
代码清单3-4 创建非聚集索引
CREATE NONCLUSTERED INDEX IX_SalesOrderDetail_ProductId_OrderQty
ON Sales.SalesOrderDetail(ProductID,OrderQty)
重新执行代码,得到如图3-4所示的执行计划,当在ProductID及OrderQty字段上创建索引后,Sort操作便消失了,并且数据的读取操作也变成了Index Seek(后续章节中,会详细介绍Scan和Seek的差异)。