2016-09-26 67 views
0

我們有多個MSSQL服務器具有相同的數據庫副本,下面的查詢返回所有服務器的有效順序(除了一個),我仔細檢查了表的設計和所有外觀除了幾臺服務器之外,其他部分都缺少索引。由學說一個MS SQL服務器爲查詢返回錯誤訂單

WITH dctrn_cte AS (
    SELECT TOP 10 a0_.Priority 
    FROM PROJECTS a0_ 
    WHERE a0_.ProjectID = 1234 
    AND (a0_.Check1 > 0 
      OR 
      a0_.Check2 > 0) 
    AND a0_.Active = 1 
    ORDER BY a0_.Priority DESC) 
    SELECT * 
    FROM (
     SELECT *, ROW_NUMBER() 
     OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte 
    ) AS doctrine_tbl 
    WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum ASC 

產生

查詢中的每個查詢的是,特定的服務器上執行時,它給出了一個隨機的順序 - 它完全忽略了ORDER BY部分。

+0

哪個'order by'?三者中唯一有意義的是第一個選擇10行。正如行編號中使用的那樣,因此在最後的順序中使用的是完全不確定的,並且不保證任何東西。 –

+0

你爲什麼使用'SELECT 0'?你認爲會發生什麼? –

回答

5

您的查詢最後有一個ORDER BY子句:doctrine_rownum。這是一個未定值列的別名:

ROW_NUMBER() 
    OVER (ORDER BY (SELECT 0)) AS doctrine_rownum 

因此,任何結果順序都是正確的順序。所有的服務器都會返回正確的結果。 Select isn't broken

PS。您在CTE內部還有一個ORDER BY,這與最終訂單無關,因爲它不會對最終結果或doctrine_rownum值施加任何順序。

該查詢由教義

產生的查詢由教義產生錯誤,無論這個學說是。

+1

CTE中的「Order by」確定CTE選擇了哪10行,因此它與最終結果並不完全無關。雖然這與結果的順序無關。 –

+0

@TabAlleman是真的。我的措辭很差。 –

+0

感謝Remus&Tab - 發佈的查詢是一個非常簡化的版本 - 我們使用[doctrine](http://www.doctrine-project.org/)構建動態查詢,而CTE部分由它提供。我將調查使用的捆綁包,看看我能否改進它。 –

-2

添加OPTION (MAXDOP 1)修復了該服務器上的訂單。

+2

「修復」和改變內容之間有區別,以便您使用的不可靠機制受到影響,並隨後趨向於匹配您想要的內容。解決這個問題將理解爲什麼它現在不是確定性的,並且改變你的數據庫代碼以確定它。 – btberry

+0

你是對的 - 我們正在尋找一種快速的方法來臨時「修復」問題而不中斷/延遲部署,特別是排序是一項高優先級要求。謝謝。 –

相關問題