2011-04-11 47 views
4

可以說我有索引是否自行提供?

create table mytable(
a VARCHAR(200) 
b VARCHAR(200) 
c VARCHAR(200) 
) 

create index on mytable (b) 

如果我選擇

select a, b, c from mytable; 

將它用b進行排序?

+0

全部4個答案都是有用的。謝謝你們! – dnuske 2011-04-11 14:59:33

回答

2

有兩種主要類型的索引:聚類和非聚類。

聚類索引確定表中的物理行順序。插入到表中(或更新相應的字段)會導致數據庫引擎重新排序數據,因此具有羣集索引的字段會正確排序。這就是爲什麼在任何表上只能有一個集羣索引的原因。

非聚類索引是列的副本,按需要排序。它們分開存在,物理行順序沒有連接到它們。這就是爲什麼可以有儘可能多的非聚類索引。

大多數情況下,單個表上的簡單選擇會按物理順序返回行,因此接收它們時按聚類索引的排序方式排列並不奇怪。

但是,這不能保證,你不應該依賴它。 如果結果集順序有任何問題,總是包含一個ORDER BY子句。

如果您通過集羣索引進行訂購,則對於數據庫引擎沒有太多工作要做,但您的意圖很明確。

如果您通過非聚類索引進行排序,那麼對於數據塊還有一些工作要做,但是(取決於表大小和數據類型),它比通過完全無索引的字段進行排序要快幾個數量級。

+0

我真正的問題是我有一個應該保存進出消息的日誌表,我想做一個正常的選擇頂端2,並相信第二行將是出來的消息。但正如你所說,我不應該依靠它並按照ID排序......至少。 – dnuske 2011-04-11 14:56:46

+0

@dnuske:如果您有嚴格增加的字段(如日誌表中的日期值)並且可能有消息類型,則可以通過'(dateval,msgtype)'創建一個聚類索引。然後ORDER BY這些字段,並採取您的TOP 2,一切都應該是好的。而且也非常快。如果日期值不*嚴格增加,則不要使用聚類索引,而是使用正常值。插入行「在中間」時會對整個表進行物理重新排序,從而導致插入性能下降,因此應避免使用。 – Tomalak 2011-04-11 15:02:08

+0

日期值只增加,非常感謝! – dnuske 2011-04-11 15:10:28

6

也許(更可能在聚集索引的情況下,我會想象),但你不能依靠這個或期望它。除非你有一個order by,假設它不會被訂購。

4

不,因爲您在示例查詢中沒有使用b上的索引。

這將使用聚簇索引掃描或表掃描。如Kieren正確指出的那樣,SQL中沒有隱式順序。即使您在查詢中使用了索引,結果順序也會受到您幾乎無法控制的事情的影響,例如查詢引擎使用的內部連接(哈希匹配,合併連接,嵌套循環)。

如果您想要訂購的結果,請使用ORDER BY

5

你應該從來沒有假設查詢返回給RDBMS的數據將以任何特定的順序。確定數據排序的唯一方法是明確請求數據庫引擎(通常使用ORDER BY子句)對查詢返回的數據進行排序和排序。

+0

而且,如果您希望按照您自己的程序對其進行排序的方式進行排序,您應該關心NLS層(例如Oracle具有'NLS_SORT = BINARY')。 – Benoit 2011-04-11 15:33:35