2009-11-24 45 views
25

我讀過的很多SQL代碼,似乎開發人員認爲默認排序順序始終成立。例如,在構建HTML選擇列表時,他們只需要SELECT id, name FROM table而不會發出ORDER BY子句。處理默認排序順序的SQL最佳實踐

從我自己的經驗看來,如果沒有給出ORDER BY子句並且沒有索引,dbms總是使用FIFO來命令數據。但是,訂單不能保證。但是,如果沒有對錶格進行更改,我從來沒有見過dbms重新排序數據。

如果表中沒有更改,您是否曾經歷過以非確定性順序選擇數據的dbms?

是否總是放置ORDER BY子句是最佳做法?

+6

,有定義,*沒有默認的排序順序*在兼容SQL的數據庫。大多數數據庫可以並且將以不同的順序返回記錄,這取決於查詢的性質,甚至執行類似查詢時索引的狀態。假設訂單很重要,您必須始終指定您想要數據的訂單。未指定順序的查詢可能無法重複。 – 2009-11-24 21:53:19

回答

38

沒有默認的排序順序。即使表格有聚集索引,也不保證按照該順序得到結果。如果您需要特定訂單,則必須使用訂單旁邊的條款。

+0

你是第一個,畢竟 – 2009-11-24 21:52:22

+0

爲第一。 – Yada 2009-11-25 00:18:18

9

如果您希望數據始終如一地出來,是的 - 您必須使用ORDER BY

6

是的。沒有ORDER BY,沒有「默認訂單」,並且不能保證您將以FIFO/LIFO或任何其他訂單取回數據。

至於開發商使用「SELECT ID,名稱FROM表」,他們要麼不稱職或不關心訂購任何產品出現英寸

3

沒有嚴重的RDBMS保證任何順序,除非你指定一個明確的ORDER BY。

其他任何只是純粹的運氣或anectodal - 如果你想要訂單,你必須指定ORDER BY - 沒有辦法繞過。

1

也許您正在閱讀的那些SQL查詢的編寫者並不關心返回的數據的順序。最佳做法是在需要的地方使用它,以確保返回結果的順序!

3

如果您想要訂購數據,唯一保證任何事情的方法(包括我知道的每個主要RDBMS系統,絕對是Sql Server和Oracle)都包含ORDER BY子句。 FIFO與沒有ORDER BY子句的情況下返回的訂單數據完全無關,並且沒有任何種類的DEFAULT排序順序的概念。然而,所謂的DEFAULT排序順序基本上是引擎獲取數據,它可以基於索引,緩存數據,同時執行的查詢,服務器上的負載等等的字面順序。

This other stackoverflow thread基本上涵蓋了與Sql Server相關的相同概念,AlexK blogged a repo來演示該行爲。

3

即使像SELECT ... FROM table這樣的簡單查詢也可以按各種順序返回數據。我知道這在理論上是真實的,我知道這在實踐中是真實的,並且當順序在後續執行之間改變時(即使表中沒有數據改變),我已經看到很多情況。

執行之間的順序更改的一個典型示例是使用並行計劃執行查詢時。由於並行操作符在底層線程生成它時返回數據,因此結果中各行的順序在每次運行之間都會有所不同。這種情況使得在你的例子中即使是簡單的SELECT也會在每次運行時返回不同的結果。

15

正如其他海報中提到的,如果您沒有指定排序順序,那麼SQL標準說結果可以按照查詢處理器發現的最有利和最有效的順序進行。

假設你爲CUSTOMER表的所有行執行簡單的無序SELECT操作,該表沒有索引並且沒有主鍵。查詢處理器完成一次直接表掃描,並按照最初插入的順序生成行(給出您看到的FIFO行爲),這很可能,甚至可能。

如果您隨後在STATE和CITY字段(按此順序)上添加索引,然後查詢WHERE STATE = 'NY',查詢處理器可能會決定掃描STATE ='NY'的索引條目而不是做全表掃描。在這種情況下,它可能會實現STATE,CITY順序中的行。

即使這是不確定的。例如,如果查詢處理器收集的統計數據顯示錶中幾乎所有的STATE值都是'NY'(可能是因爲數據庫是針對基於Albany的設備租賃業務),則可能會決定表掃描實際上更便宜比索引掃描,你會再次看到FIFO。

最好學習一些關於數據庫如何計劃查詢的基礎知識。您可以使用EXPLAIN語句來查看DBMS如何執行任何給定的查詢,然後使用它來優化查詢,在某些情況下按幾個數量級。這是一個迷人而有用的學習領域。

3

在我與SQL的經驗,大部分時間我不指定ORDER BY在SQL,因爲該記錄集顯示在「客戶端」網格型控制等地方動態排序是支持的 - 在這種情況下,通過SQL排序是不必要的,因爲無論如何都會檢查客戶端。

這也做客戶端,因爲可能會使用相同的查詢以不同的順序在不同的地方顯示數據。

因此,這是擺在一個ORDER BY只有最好的實踐中,當

  • 數據的順序是重要;和
  • 排序在數據庫級別更高效。

即,如果前端顯影劑將是「重新排序」也無妨,那麼就沒有點,因爲它不太可能節省總的處理時間。

+0

這是一個很好的方面,有一個客戶端將自行排序。當然,並不是所有查詢都發送到客戶端應用程序,有的正在創建導出文件,而ordierng可能非常重要。但是,是的,做最有效的做法是很好的,如果你打算在客戶端重新排序,不排序可能是最有效的。但是,我會測試兩種方式。 – HLGEM 2015-05-28 14:52:59

0

我正在寫這個的情況下,如果有人想像我這樣使用它。

嗯,我得到了令人滿意的默認排序順序,讓我們說對於日誌表,排序索引。例如,我通常對日誌表(LIFO)的最後一行感興趣,所以我使用DateTime DESC作爲順序。我也嘗試過在主鍵旁邊的其他字段(整數)上添加索引,並且它工作。

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL, 
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] 

或在SSMS中...

enter image description here