非聚集索引与ORDER BY排序的问题

本文通过实例详细探讨了非聚集索引在SELECT语句中的使用,特别是涉及ORDER BY子句时如何选择合适的索引。文章通过创建和分析不同类型的索引,展示了在不同查询场景下,数据库如何选择执行计划,包括何时使用聚集索引、非聚集索引以及索引覆盖等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 写写如果SELECT列表中,使用*和不使用*的索引使用情况,如果错了,希望各位改正。

例子以Northwind.dbo.Orders表为例,因为对这个表比较熟悉。
先创建出示例数据库:
CREATE DATABASE Test;
GO
USE Test
GO
--Northwind.dbo.Orders表的数据导到我们的测试数据库当中.
SELECT * INTO dbo.Orders FROM Northwind.dbo.Orders;
GO

--现在为Test.dbo.Orders表添加几个索引
--
建立OrderID为键值的聚集索引
CREATE UNIQUE CLUSTERED INDEX cidx_OrderID ON dbo.Orders(OrderID);
--建立CustomerID,EmployeeID复合的非聚集索引
CREATE INDEX idx_CustomerID_EmployeeID ON dbo.Orders(CustomerID,EmployeeID);
--建立OrderDate为键值的非聚集索引,并包含ShipVia,Freight
CREATE INDEX idx_OrderDate ON dbo.Orders(OrderDate) INCLUDE(ShipVia,Freight);
--

### SqlServer 中聚集索引非聚集索引的区别及应用场景 #### 基本概念 聚集索引(Clustered Index)定义了表中数据的物理存储顺序。当创建一个聚集索引时,表中的数据会按照索引键值的逻辑顺序重新排列并存储。这意味着每张表最多只能有一个聚集索引,因为数据的实际存储位置只能有一种排序方式[^1]。 相比之下,非聚集索引(Non-Clustered Index)并不改变表中实际数据的物理存储顺序。它通过建立额外的数据结构来指向实际数据的位置。这种索引可以有多个存在于同一张表上,因为它仅维护了一个独立于数据存储之外的查找路径[^2]。 --- #### 数据存储差异 对于聚集索引而言,其叶节点实际上就是数据页本身,也就是说,当我们查询某个范围内的记录时,可以直接从磁盘读取这些连续存储的数据页面。而非聚集索引则不同,它的叶子层保存着对应行的指针或者ROWID(具体取决于实现),这使得每次定位到目标数据都需要经历一次额外的跳跃操作——即先找到索引项再跳转至真实数据所在地址[^3]。 --- #### 性能影响因素分析 在性能方面考虑如下几点: - **插入/更新成本** 如果在一个经常发生增删改动作的大规模动态事务型环境中工作,则应谨慎对待是否要在活跃变动字段之上设置为聚簇形式;由于每一次调整都会牵涉到底层数组整体位移重排过程,因此相对耗资源较多。 - **检索速度对比** 对于那些主要依赖单一关键字快速定址需求的应用程序来说(比如主键搜索),采用CLUSTERED INDEX往往能够带来更快响应时间效果;而对于多条件组合过滤复杂模式下可能反而不如NONCLUSTERED版本表现优越[]. --- #### 应用场景推荐 以下是针对不同类型的工作负载给出的一些指导原则: - 使用**聚集索引**的情况包括但不限于: * 表中存在唯一标识符作为主键(primary key), 并且该属性很少被修改. * 查询请求倾向于按一定次序扫描大片区域而不是随机抽取个别项目. - 推荐选用**非聚集索引**的情形主要有以下几个方面: a. 列内含有很多互异数值; b. SQL语句最终输出结果集中只涉及少数几条记录; c. ORDER BY子句里指定的那个维度正好匹配当前待建树形目录对象[]; 另外值得注意的一点是关于所谓“覆盖索引”的概念,在某些特殊情况下如果我们的non-cluster index已经完全涵盖了所关心的所有字段信息而无需回溯源文件的话那么整个执行计划将会更加高效快捷. ```sql -- 创建聚集索引示例 CREATE CLUSTERED INDEX idx_clustered ON table_name (column_name); -- 创建非聚集索引示例 CREATE NONCLUSTERED INDEX idx_nonclustered ON table_name (another_column); ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值