聚集索引和排序
Clustered Index and Sorting
例如,如果您 运行 以下查询,行可能会以任何顺序返回:
select *
from [table_a];
聚簇索引根据您选择的任何列对 table 进行排序。
话虽这么说,如果我在 [column_a], [column_b], and [column_c]
和 运行 上有一个来自上面的相同查询的聚簇索引,数据返回时是否总是会根据该顺序排序,因为这是聚簇索引创建于?
更多说明:
如果我在不在索引中的内容上添加 ORDER BY
子句,执行计划将有一个排序运算符。
如果我在聚集索引中使用的所有列上都有一个 ORDER BY
子句,则执行计划将没有排序运算符。
这就是我一开始问这个问题的原因。
SQL 报告的经验法则是,如果您希望结果集按特定顺序排列,那么您总是 需要添加适当的 ORDER BY
子句。现在,SQL 服务器可能会选择按 column_a
、column_b
和 column_c
的顺序扫描索引,因此 return 结果在那个顺序,但没有保证会发生这种情况。但是,如果您使用以下查询:
SELECT *
FROM [table_a]
ORDER BY [column_a], [column_b], [column_c];
然后在三列上建立一个索引,按照与上述 ORDER BY
子句相同的顺序应该使用并且据说 覆盖 整个查询。
注意:问题是交叉发布的here。
if I have a clustered index on [column_a], [column_b], and [column_c] and run the same query from above, will the data ALWAYS come back sorted based on that order since that's the order that the clustered index was created on?
没有
SQL 服务器不保证它将 return 数据以任何顺序 除非您指定顺序 。通过简单地创建一个指向不同列的覆盖非聚集索引,很容易证明事情会出错:
但事情也可能以其他方式发生变化,例如当并行或分区发挥作用并且 SQL 服务器重新组装来自不同线程的数据时,或者当使用连接或过滤器的查询变得更加复杂时,除了聚簇索引扫描之外的其他计划是有意义的。省略 order by 子句是在告诉 SQL 服务器:“我不关心顺序。”
另外,澄清一点:
If I have an ORDER BY clause on all the columns used in the clustered index, the execution plan will not have a sort operator.
...仅当列以与键定义完全相同的顺序列出时才为真。 ORDER BY c, b, a
是“所有列”,但它显然会产生不同的输出(并且需要某种类型的排序操作才能到达那里)。
如果您期望并希望对特定顺序感到满意,请始终使用 ORDER BY 子句。
延伸阅读:
- No Seatbelt - Expecting Order without ORDER BY(康纳·坎宁安)
- Without ORDER BY, there is no default sort order.(亚历山大·库兹涅佐夫)
- T-SQL Tuesday #56: SQL Server Assumptions(我 - 参见#3)
- Bad Habits to Kick : Relying on undocumented behavior(还有我)
- Why is SSMS inserting new rows at the top of a table not the bottom?(dba.se 问题)
例如,如果您 运行 以下查询,行可能会以任何顺序返回:
select *
from [table_a];
聚簇索引根据您选择的任何列对 table 进行排序。
话虽这么说,如果我在 [column_a], [column_b], and [column_c]
和 运行 上有一个来自上面的相同查询的聚簇索引,数据返回时是否总是会根据该顺序排序,因为这是聚簇索引创建于?
更多说明:
如果我在不在索引中的内容上添加 ORDER BY
子句,执行计划将有一个排序运算符。
如果我在聚集索引中使用的所有列上都有一个 ORDER BY
子句,则执行计划将没有排序运算符。
这就是我一开始问这个问题的原因。
SQL 报告的经验法则是,如果您希望结果集按特定顺序排列,那么您总是 需要添加适当的 ORDER BY
子句。现在,SQL 服务器可能会选择按 column_a
、column_b
和 column_c
的顺序扫描索引,因此 return 结果在那个顺序,但没有保证会发生这种情况。但是,如果您使用以下查询:
SELECT *
FROM [table_a]
ORDER BY [column_a], [column_b], [column_c];
然后在三列上建立一个索引,按照与上述 ORDER BY
子句相同的顺序应该使用并且据说 覆盖 整个查询。
注意:问题是交叉发布的here。
if I have a clustered index on [column_a], [column_b], and [column_c] and run the same query from above, will the data ALWAYS come back sorted based on that order since that's the order that the clustered index was created on?
没有
SQL 服务器不保证它将 return 数据以任何顺序 除非您指定顺序 。通过简单地创建一个指向不同列的覆盖非聚集索引,很容易证明事情会出错:
但事情也可能以其他方式发生变化,例如当并行或分区发挥作用并且 SQL 服务器重新组装来自不同线程的数据时,或者当使用连接或过滤器的查询变得更加复杂时,除了聚簇索引扫描之外的其他计划是有意义的。省略 order by 子句是在告诉 SQL 服务器:“我不关心顺序。”
另外,澄清一点:
If I have an ORDER BY clause on all the columns used in the clustered index, the execution plan will not have a sort operator.
...仅当列以与键定义完全相同的顺序列出时才为真。 ORDER BY c, b, a
是“所有列”,但它显然会产生不同的输出(并且需要某种类型的排序操作才能到达那里)。
如果您期望并希望对特定顺序感到满意,请始终使用 ORDER BY 子句。
延伸阅读:
- No Seatbelt - Expecting Order without ORDER BY(康纳·坎宁安)
- Without ORDER BY, there is no default sort order.(亚历山大·库兹涅佐夫)
- T-SQL Tuesday #56: SQL Server Assumptions(我 - 参见#3)
- Bad Habits to Kick : Relying on undocumented behavior(还有我)
- Why is SSMS inserting new rows at the top of a table not the bottom?(dba.se 问题)