我有一个表,它捕获用户正在运行的主机平台。该表的定义很简单:
IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL
BEGIN
CREATE TABLE [Auth].[ActivityPlatform] (
[ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL
,[ActivityPlatformName] [varchar](32) NOT NULL
,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC)
,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC)
) ON [Auth];
END;
GO它存储的数据是基于使用他们浏览器中的信息的JavaScript方法枚举的(我不知道更多,但如果需要的话可以查出来):

但是,当我执行一个没有显式SELECT的基本ORDER BY时,执行计划显示它使用UNIQUE NONCLUSTERED索引来进行排序而不是CLUSTERED索引。
SELECT * FROM [Auth].[ActivityPlatform] 
当显式指定ORDER BY时,它将按照ActivityPlatformId正确排序。
SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS没有显示表碎片。
我错过了什么会导致这一切?我一直认为表是在聚集索引的基础上创建的,因此它应该不需要指定ORDER BY就可以隐式地进行排序。Server在选择UQ时的偏好是什么?在表的创建中是否需要指定什么?
发布于 2018-03-19 14:44:01
不,排序不是隐式的,不应该依赖。实际上,在第一个工具提示中,您可以看到它被显式地声明为Ordered = False。这意味着Server根本没有做任何事情来实现任何排序。你观察到的只是它所做的事情,而不是它试图做的事情。
如果希望能够预测可靠的排序顺序,请键入ORDER BY。句号。当您不添加ORDER BY时,您可能会观察到什么可能是有趣的,但不能依赖于它的一贯行为。实际上,在这篇文章中,请参阅#3,我展示了查询的输出可以通过其他人添加索引来改变。
Server在选择UQ时的偏好是什么?
UNIQUE NONCLUSTERED索引包含聚类键,因此它涵盖了查询。在本例中,您的表只有两列,因此聚集索引和非聚集索引包含相同的数据(只是排序不同)。它们都是相同的大小,所以优化器可以任意选择。它选择非聚集索引是实现细节。
我管这叫“抛硬币”
https://dba.stackexchange.com/questions/201678
复制相似问题