簡體   English   中英

ROW_NUMBER 沒有 ORDER BY

[英]ROW_NUMBER Without ORDER BY

我必須在現有查詢中添加行號,以便跟蹤已添加到 Redis 中的數據量。 如果我的查詢失敗,那么我可以從在其他表中更新的那行開始。

查詢以從表中的 1000 行開始獲取數據

SELECT * FROM (SELECT *, ROW_NUMBER() OVER (Order by (select 1)) as rn ) as X where rn > 1000

查詢工作正常。 如果我可以在不使用 order by 的情況下獲得行號。

這里的select 1是什么?

查詢是優化的還是我可以通過其他方式來完成。 請提供更好的解決方案。

無需擔心在ORDER BY表達式中指定常量。 以下引用自Itzik Ben-Gan編寫的Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions (可從 Microsoft 免費電子書網站免費下載):

如前所述,窗口順序子句是強制性的,並且 SQL Server 不允許基於常量的排序,例如 ORDER BY NULL。 但令人驚訝的是,當傳遞基於返回常量的子查詢的表達式時(例如 ORDER BY (SELECT NULL)),SQL Server 會接受它。 同時,優化器取消嵌套或擴展表達式,並意識到所有行的順序都相同。 因此,它從輸入數據中刪除了排序要求。 這是演示此技術的完整查詢:

SELECT actid, tranid, val,
 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM dbo.Transactions;

在此處輸入圖片說明

在Index Scan迭代器的屬性中觀察Ordered屬性為False,意味着迭代器不需要按照索引鍵順序返回數據


以上意味着當您使用常量排序時不會執行。 我強烈建議閱讀本書,因為Itzik Ben-Gan深入描述了窗口函數的工作原理以及如何在使用它們時優化各種情況。

嘗試order by 1 閱讀錯誤消息。 然后order by (select 1)恢復order by (select 1) 意識到寫這篇文章的人在某個時候閱讀了錯誤消息,然后決定正確的做法是欺騙系統不引發錯誤,而不是意識到錯誤試圖提醒他們注意的基本事實。

表沒有固有的順序。 如果您想要某種可以依賴的排序形式,則由您為任何ORDER BY子句提供足夠的確定性表達式,以便每一行都被唯一標識和排序。

其他任何事情,包括誘使系統不發出錯誤,都希望系統在不使用提供給您的工具的情況下做一些明智的事情來確保它做一些明智的事情 - 一個明確指定的ORDER BY子句。

您可以使用任何文字值

前任

order by (select 0)

order by (select null)

order by (select 'test')

有關更多信息,請參閱https://exploresql.com/2017/03/31/row_number-function-with-no-specific-order/

這里的選擇 1 是什么?

在這種情況下,查詢的作者並沒有真正考慮任何特定的排序。 ROW_NUMBER需要ORDER BY clause因此提供它是一種滿足解析器的方法。

按“常量”排序將創建“不確定”順序(查詢優化器能夠選擇它認為合適的任何順序)。

最簡單的思考方式是:

ROW_NUMBER() OVER(ORDER BY 1)    -- error
ROW_NUMBER() OVER(ORDER BY NULL) -- error

為“技巧”查詢優化器提供常量表達式的可能場景很少:

ROW_NUMBER() OVER(ORDER BY (SELECT 1)) -- already presented

其他選項:

ROW_NUMBER() OVER(ORDER BY 1/0)       -- should not be used
ROW_NUMBER() OVER(ORDER BY @@SPID)
ROW_NUMBER() OVER(ORDER BY DB_ID())
ROW_NUMBER() OVER(ORDER BY USER_ID())

db<>小提琴演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM