如果数据保持不变,是否有方法为同一SQL查询获得不同的结果?

如果数据保持不变,是否有方法为同一SQL查询获得不同的结果?,sql,tsql,sql-server-2008,Sql,Tsql,Sql Server 2008,当我运行这个查询时,我会间歇性地得到一个不同的结果集……有时它会给出1363,有时1365,有时1366个结果。数据没有改变。是什么导致了这种情况?有没有办法防止这种情况?查询如下所示: SELECT * FROM ( SELECT RC.UserGroupId, RC.UserGroup, RC.ClientId

当我运行这个查询时,我会间歇性地得到一个不同的结果集……有时它会给出1363,有时1365,有时1366个结果。数据没有改变。是什么导致了这种情况?有没有办法防止这种情况?查询如下所示:

SELECT * 
FROM 
    (
            SELECT  
                        RC.UserGroupId,
                        RC.UserGroup,
                        RC.ClientId AS CLID,                     
                        CASE WHEN T1.MultipleClients = 1 THEN RC.Salutation1 ELSE RC.DisplayName1 END AS szDisplayName,
                        T1.MultipleClients,
                        RC.IsPrimaryRecord,
                        RC.RecordTypeId,
                        RC.ClientTypeId,
                        RC.ClientType,
                        RC.IsDeleted,
                        RC.IsCompany,                                            
                        RC.KnownAs,
                        RC.Salutation1,
                        RC.FirstName, 
                        RC.Surname,                   
                        Relationship, 
                        C.DisplayName Client,
                        RC.DisplayName RelatedClient, 
                        E.Email,                                                            
                        RC.DisplayName  + ' is the ' + R.Relationship + ' of ' + C.DisplayName Description,
                        ROW_NUMBER() OVER (PARTITION BY E.Email ORDER BY Relationship DESC) AS sequence_id


            FROM 
                        SSDS.Client.ClientExtended C 
                                                                              INNER JOIN 
                        SSDS.Client.ClientRelationship R WITH (NOLOCK)ON C.ClientId = R.ClientID 
                                                                              INNER JOIN 
                        SSDS.Client.ClientExtended RC WITH (NOLOCK)ON R.RelatedClientId = RC.ClientId
                                                                              LEFT OUTER JOIN
                        SSDS.Client.Email E WITH (NOLOCK)ON RC.ClientId = E.ClientId                 
                                                                              LEFT OUTER JOIN 
                        SSDS.Client.UserDefinedData UD WITH (NOLOCK)ON C.ClientId = UD.ClientId AND C.UserGroupId = UD.UserGroupId 
                                                                              INNER JOIN                                                                 

                        (
                              SELECT 
                                          E.Email, 
                                          CASE WHEN (COUNT(DISTINCT RC.DisplayName) > 1) THEN 1 ELSE 0 END AS MultipleClients 

                              FROM
                                          SSDS.Client.ClientExtended C 
                                                                                                INNER JOIN 
                                          SSDS.Client.ClientRelationship R WITH (NOLOCK)ON C.ClientId = R.ClientID 
                                                                                                INNER JOIN 
                                          SSDS.Client.ClientExtended RC WITH (NOLOCK)ON R.RelatedClientId = RC.ClientId
                                                                                                LEFT OUTER JOIN
                                          SSDS.Client.Email E WITH (NOLOCK)ON RC.ClientId = E.ClientId                 
                                                                                                LEFT OUTER JOIN 
                                          SSDS.Client.UserDefinedData UD WITH (NOLOCK)ON C.ClientId = UD.ClientId AND C.UserGroupId = UD.UserGroupId

                              WHERE 
                                          Relationship IN ('z-Group Principle', 'z-Group Member ')           
                                          AND E.Email IS NOT NULL

                              GROUP BY E.Email 

                        ) T1 ON E.Email = T1.Email


            WHERE 

                                                Relationship IN ('z-Group Principle', 'z-Group Member ')           
                                                AND E.Email IS NOT NULL                                         
    ) T


WHERE       
            sequence_id = 1
            AND T.UserGroupId IN (Select * from iCentral.dbo.GetSubUserGroups('471b9cbd-2312-4a8a-bb20-35ea53d30340',0))         
            AND T.IsDeleted = 0           
            AND T.RecordTypeId = 1 
            AND T.ClientTypeId IN
            (
                        '1',              --Client
                        '-1652203805'    --NTU                      
            )        

        AND T.CLID NOT IN
          (
            SELECT DISTINCT  
                               UDDF.CLID
            FROM
                   SLacsis_SLM.dbo.T_UserDef UD WITH (NOLOCK) 
                          INNER JOIN
                   SLacsis_SLM.dbo.T_UserDefData UDDF WITH (NOLOCK)
                   ON UD.UserDef_ID = UDDF.UserDef_ID
                          INNER JOIN
                   SLacsis_SLM.dbo.T_Client CLL WITH (NOLOCK)
                   ON CLL.CLID = UDDF.CLID AND CLL.UserGroup_CLID = UD.UserID

            WHERE 
                           UD.UserDef_ID in    
                                    (
                                    'F68F31CE-525B-4455-9D50-6DA77C66FEE5',                                    
                                    'A7CECB03-866C-4F1F-9E1A-CEB09474FE47'  
                                    )

                           AND UDDF.Data = 'NO'
           ) 


ORDER BY T.Surname
编辑:

我已经删除了所有NOLOCK(包括视图和udf中的NOLOCK),但仍然存在相同的问题。对于嵌套的select(T),我每次都会得到相同的结果,如果我在查询开始时将T的结果集放入临时表,并将其连接到临时表而不是嵌套的select,那么每次运行查询时,最终的结果集都是相同的

EDIT2:

我对ROW_NUMBER()进行了更多的阅读……我通过电子邮件进行分区(其中有重复项)并通过关系进行排序(其中只有1个关系)。这会导致查询不确定吗?有没有办法解决这个问题

EDIT3:

如果有人感兴趣,以下是实际执行计划。是否可以看到它正在以执行计划中的读取提交方式运行?我使用WinMerge比较了这些文件,唯一的区别似乎是计数(ActualRows=“”)

EDIT4:

这项工作:

SELECT * FROM 
(
   SELECT *, 
             ROW_NUMBER() OVER (PARTITION BY B.Email ORDER BY Relationship DESC) AS sequence_id
             FROM
            (

                                    SELECT DISTINCT  
                                    RC.UserGroupId,
                                    ...
            ) B...
EDIT5:

当在一行中运行相同的ROW_NUMBER()查询(在原始问题中为T,只需选择RC.DisplayName和ROW_NUMBER)两次时,对于某些人,我会得到不同的排名:

是否有人能很好地解释/举例说明为什么或如何在每次运行包含重复项的结果集时,对其进行不同的排序,并最终更改结果的数量

EDIT6:


好吧,我想这对我来说是有意义的。当两个人拥有相同的电子邮件地址(例如一对夫妻)和关系时,就会发生这种情况。我猜在这种情况下,他们的ROW_NUMBER()排名是任意的,每次运行时都会发生变化。

您对NOLOCK的使用意味着您正在进行脏读,将看到未提交的数据、将回滚的数据、暂时的和不一致的数据等

把这些脱下来,再试一次,报告请求

编辑:删除了NOLOCK的某些选项

  • 数据确实在变化
  • 某些参数或筛选器正在更改(例如GETDATE)
  • 每次在不同的内核上运行一些浮点比较
    在dba.se上可以看到这一点
  • UDF或视图中嵌入的NOLOCK(例如iCentral.dbo.GetSubUserGroups)

  • 最近有一个KB解决了ROW_NUMBER()的问题。。。有关详细信息,请参阅

    然而,这个知识库表明,当调用并行性来执行时,这是一个问题,从您的执行计划来看,我看不到这一点。但是MS在一种情况下发现了一个问题这一事实让我有点担心——也就是说,对于一个足够复杂的查询,是否会出现同样的问题(而且您的执行计划看起来确实足够大)


    因此,可能值得检查SQL Server 2008的修补程序级别。

    这可能与订购有关。您有一个序列号,定义为按关系排序的行号。您总是可以通过关系获得合理的顺序,但除此之外,您的行数将是随机的。因此,每次都可以得到序列号为1的不同行。这反过来会影响where子句,您可以得到不同数量的结果。若要解决此问题以获得一致的结果,请将另一个字段添加到行号的order by。使用主键确保结果一致。

    正如我昨天在评论中所说的,重复
    E.Email、Relationship
    值的行编号是任意的


    要使其具有确定性,您需要按B进行
    分区。电子邮件顺序按关系描述,SomeUniqueColumn
    。有趣的是,虽然使用相同的执行计划,但它在运行之间会发生变化。我假设这是散列连接的结果。

    我认为您的问题是分区上的第一行不是确定性的。我怀疑电子邮件和关系不是唯一的

        ROW_NUMBER() OVER (PARTITION BY E.Email ORDER BY Relationship DESC) AS sequence_id 
    
    稍后检查分区的第一行

        WHERE   T.sequence_id = 1
            AND T.UserGroupId ... 
    
    如果第一行是任意的,那么您将得到任意的where比较。您需要向订单中添加一个完整的唯一密钥。如果没有唯一的密钥,那么您需要创建一个密钥或使用任意结果。即使在具有聚集主键的表上,也不能保证选择行顺序,除非整个主键在sort子句中。

    U只能使用

    Order by
    
    没有人的邀请

    ROW_NUMBER() OVER (ORDER BY Relationship DESC) AS sequence_id 
    

    它运行的隔离级别是什么?代码中是否有任何非确定性函数?我已经扫描了这段代码,但你说它“看起来像这样”,所以假设它不准确。@p.campbell:SQL基本上是一样的,我刚刚删除了where in中的一些附加过滤条件clause@woggles:您可以使用NOLOCK覆盖此选项,该选项与读取未提交选项相同。您可以识别有时显示有时不显示的2或3行吗?您可能可以将输出复制到Excel,进行排序,并直观地查看匹配停止的位置(可能只是选择一个键而不是选择*)。我正在寻找链接,但也有一个几周前制作的post Remus链接到一个测试,该测试显示,即使表格不使用
    NOLOCK
    @JNK:yep,请参见演示,您仍然可以看到不可重复和幻影读取@gbn:removed所有带有(无锁)的,但我仍然有相同的问题。每次运行query@woggles-您是否删除了所有视图,包括子查询?是的-我将再次检查是否所有被查询的视图都没有使用NOLOCK:将在一个分区中跟进其他两个用户的答案相同。当我开始做这件事的时候