DISTINCT 不将两个相等的值减为一

jim*_*gee 18 sql-server system-tables distinct

谁能解释下面的情况,其中两个看似相等的值没有减少DISTINCT

显示“SBS_UCS_DISPATCH”的两个值的屏幕截图

上面的查询是SELECT DISTINCT name FROM master.sys.dm_os_spinlock_stats where name = 'SBS_UCS_DISPATCH';

等效方法SELECT name FROM master.sys.dm_os_spinlock_stats where name = 'SBS_UCS_DISPATCH' GROUP BY name;也执行相同的操作,并且添加HAVING COUNT(1) > 1不会产生行。

@@VERSIONMicrosoft SQL Server 2019 (RTM-CU13) (KB5005679) - 15.0.4178.1 (X64) 2021 年 9 月 23 日 16:47:49 版权所有 (C) 2019 Microsoft Corporation 企业版:Windows Server 上基于核心的许可(64 位) 2016 标准 10.0(内部版本 14393:)

Mar*_*ith 16

看起来DISTINCT在简化过程中得到了优化。

select distinct name 
FROM master.sys.dm_os_spinlock_stats 
OPTION (QUERYTRACEON 8606,QUERYTRACEON 3604)
Run Code Online (Sandbox Code Playgroud)

给予

*** Input Tree: ***
        LogOp_GbAgg OUT(QCOL: DM_OS_SPINLOCKSTATS.name,) BY(QCOL: DM_OS_SPINLOCKSTATS.name,)

            LogOp_Project

                LogOp_Project QCOL: DM_OS_SPINLOCKSTATS.name

                    LogOp_Project

                        LogOp_StreamingTabUdfRESULT(QCOL: DM_OS_SPINLOCKSTATS.name QCOL: DM_OS_SPINLOCKSTATS.collisions QCOL: DM_OS_SPINLOCKSTATS.spins QCOL: DM_OS_SPINLOCKSTATS.spins_per_collision QCOL: DM_OS_SPINLOCKSTATS.sleep_time QCOL: DM_OS_SPINLOCKSTATS.backoffs)


                        AncOp_PrjList 

                    AncOp_PrjList 

                AncOp_PrjList 

            AncOp_PrjList 

*******************
Run Code Online (Sandbox Code Playgroud)

然后GbAgg消失在简化树中

*** Simplified Tree: ***
        LogOp_StreamingTabUdfRESULT(QCOL: DM_OS_SPINLOCKSTATS.name QCOL: DM_OS_SPINLOCKSTATS.collisions QCOL: DM_OS_SPINLOCKSTATS.spins QCOL: DM_OS_SPINLOCKSTATS.spins_per_collision QCOL: DM_OS_SPINLOCKSTATS.sleep_time QCOL: DM_OS_SPINLOCKSTATS.backoffs)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我假设有一些元数据表明name是唯一的,尽管查询结果相反,但我不知道如何证明这一点。

解决此问题的一种方法如下。

SELECT DISTINCT name COLLATE Latin1_General_100_CI_AS
FROM master.sys.dm_os_spinlock_stats 
WHERE name COLLATE Latin1_General_100_CI_AS = 'SBS_UCS_DISPATCH'
Run Code Online (Sandbox Code Playgroud)

一般来说,即使name在一种排序规则下是唯一的,那么它仍然可能具有不同collate语义的重复项。对我来说,原始的列排序规则是Latin1_General_CI_AS这样的,这不会改变不区分大小写、区分重音的性质,但足以保留GbAgg计划中的内容。

在此输入图像描述

SELECT ca.name, 
       COUNT(*) AS Count,  
       SERVERPROPERTY('ProductVersion') AS [version]
FROM master.sys.dm_os_spinlock_stats 
CROSS APPLY (VALUES(name COLLATE Latin1_General_100_BIN)) ca(name)
GROUP BY ca.name
HAVING COUNT(*) > 1
Run Code Online (Sandbox Code Playgroud)

在我的开发实例上返回以下内容

姓名 数数 版本
LOGPOOL_FREEBUFMGR 2 16.0.1050.5
SBS_UCS_DISPATCH 2 16.0.1050.5

因此SBS_UCS_DISPATCH,并不是唯一一个被复制的人。

对我来说,其他列中的值都是0这些。因此,我不清楚如果遇到这些自旋锁,整个行是否会被重复,或者是否需要聚合它们。

无论如何,受影响的类型不是除“内部使用”之外记录的类型。