2010-06-20 16 views
0

我的理解是,訪問特定行的最快方法是通過它的ROWID。在INFORMIX-SE 7.3中,當我執行SELECT ROWID FROM table時,我注意到它的值是SERIAL [INT]類型。在Oracle中,它們是SERIAL [HEX]。有沒有人曾經使用ROWID進行實際使用?如果我想查找添加到表中的最新行,SELECT MAX(ROWID) FROM table會比說SELECT MAX(pk_id) FROM table更快,更可靠,其中pk_id是用戶創建的SERIAL列?你有什麼其他的實際用途讓ROWID爲你工作?ROWID是否由SQL DBMS內部索引唯一?

+1

ROWID在這些數據庫中的含義完全不同。嘗試堅持關於您使用的平臺的問題,因爲一個平臺的「正確」答案不適用於另一個平臺。例如,從oracle中選擇MAX(ROWID)通常不會插入最新的記錄。 – 2010-06-20 23:25:09

回答

1

在Informix-SE中,ROWID基本上是C-ISAM文件中用於存放表的記錄號。 SE只處理固定大小的記錄,當然(沒有VARCHAR數據)。

在Informix Dynamic Server中,ROWID是(a)更復雜的(頁碼加槽號)和(b)並不總是存在的(碎片表不會公開ROWID,除非該表是用ROWIDS創建的,情況下,ROWID是一個物理列,所有的索引) - 注意!

如果沒有數據被刪除,並且您正在使用SE,那麼選擇具有最大ROWID的行將是最近添加的行。如果一行被刪除,那麼該空間將最終被重用,然後最近添加的行不再是具有最大ROWID的行。 (因爲各種複雜的原因,IDS並未作出承諾。)

ROWID的SE實現不會將ROWID存儲在表中,也不會爲其創建索引,但它不需要索引,因爲它知道去哪裏查找數據的公式(數據文件中的偏移量= ROWID * RowSize),在RowSize上給出或加上一個或減去一個ROWID或兩者。

至於爲ROWID,之前碎片加入IDS這是使用的樣式實際使用是選擇表中的權益記錄ROWID值的列表,在內存中維護該列表:

SELECT ROWID 
    FROM InterestingTable 
WHERE SomeColumn = xxx 
    AND AnotherColumn < yyy; 

然後,程序可以一次呈現這些行,通過存儲的ROWID獲取當前數據。記錄的ROWID在程序運行時不會改變。這確保了顯示記錄時顯示當前數據 - 無論是來自當前用戶還是其他人的編輯。

有一個您熟悉的程序,ISQL Perform,其行爲如此。而且它不適用於碎片表(必須在IDS中; SE不支持碎片表),除非它們使用帶有WITH ROWIDS子句的物理ROWID列創建。

+0

我考慮使用ROWID的唯一目的是爲了在查找表中最近添加的行時具有更快的性能。 'SELECT MAX(ROWID)FROM transactions'與'SELECT MAX(pk_serial)FROM transactions'。由於我的應用程序是使用INFORMIX-SQL編寫的並且使用了Standadrd Engine(SE),所以ROWID是一個SERIAL [INT],新添加的行放在數據文件的末尾。行不會被用戶刪除,但歷史行不會在日常重組中重新加載。我認爲,如果行被刪除,它們會被標記但不會被物理刪除,因此它們的ROWID不會被重新分配。 – 2010-06-20 18:33:54

+0

@Frank:關鍵是不要嘗試在(其他)表中存儲ROWID值。儘管在程序運行時ROWID通常是穩定的(例如,除非有人設法修改表),但不應將ROWID值存儲在數據庫中。通過將記錄結束標記從換行符'\ n'更改爲NUL'\ 0',將行標記爲已刪除。但是,空間*可供重用。 – 2010-06-21 02:05:49

+0

我不打算使用ROWID來存儲它,只是爲了在查詢中使用它來定位最近添加的行,如'SELECT MAX(ROWID)FROM table',另外系統是單用戶和用戶不允許刪除任何行。 – 2010-06-21 04:02:16

2

你的理解不一定是正確的。 SQL Server中的ROWID屬性主要用於複製,以確保表具有單字段唯一索引值。通過這種方式,複製系統不必考慮您的設計可能使用的任何特定主鍵語義,同時仍然能夠通過單個列識別每行。除非它是合併複製發佈的一部分,否則不需要任何表來創建ROWID列,所以它不像Oracle那樣每個表都有。它也沒有達到相同的目的(它們是Guid's - 或者SQL Server上的T-SQL術語中的uniqueidentifier),並且是隨機的,而不是像Oracle上的順序整數。

從表中檢索行的最快方法是通過聚集索引訪問行。一張表只能有一個聚集索引,因爲它決定了磁盤上行的物理順序。此外,如果表具有主鍵,則主鍵是聚簇索引。雖然可以聲明一個沒有主鍵的表並將聚集索引分配給別的東西,但是我不能(理解我的頭頂)明白爲什麼你想要這樣做(或者出於實際的目的,如何證明擁有沒有主鍵的表格)。

簡而言之,這意味着退休行的最快方式是使用表的主鍵。除非ROWID主鍵(這肯定是可行的),那麼它不是最快的方法。

+0

+1非常簡潔的答案。我只想簡單地說,儘管SQL主鍵默認是集羣化的,但它們不會(如您所指出的那樣)*。至於爲什麼會這樣,例如,你的主鍵可能是一個GUID,並且聚集索引可能在順序int字段上。我在一些產品數據庫中進行了這種更改,這些產品數據庫聚集了GUID並在該字段上具有FK。這是一種在不改變設計的情況下提高現有數據庫的INSERT性能的方法。 – 2010-06-20 05:14:07

+0

1)也許我沒有明確表達我的問題,我的意思是「......通過SQL服務器?」不是來自Microsoft的SQL Server產品,我的意思是任何SQL引擎。 2)您的評論與我提出的問題無關,「有人曾經使用ROWID進行實際使用?」或查找最近添加的行。 3)我對集羣非常熟悉,請參閱前面發佈的「customer.id [serial] joining transaction.id [integer] vs. ...」問題,以及4)@ Randolph-SQL主鍵默認情況下不會集羣,除非你明確地爲它們創建了一個聚集索引。 – 2010-06-20 05:28:37

+0

@Frank:1)如果你指的是* any * SQL引擎,那麼'ROWID'概念就會出來,因爲它不是一個標準的SQL組件。並非所有引擎都有。 2)它可以服務的唯一實際目的完全取決於RDBMS。如果你希望它是一般的,那麼沒有合適的答案。 3)不知道你在做什麼。如果您熟悉集羣,那麼您應該知道這是檢索或加入行的最快方法。 4)這是不正確的。主鍵*在幾乎每個RDBMS中都默認爲聚簇。 – 2010-06-20 13:28:51

1

也許術語「RDBMS」而不是「SQL服務器」?

將任何目的附加到ROWID是一個壞主意。特別是如果你習慣於刪除和重新創建表格。如果你的桌子需要一個SERIAL PK,那麼這就是它應該有的。在您的應用程序中使用ROWIDs沒有用處。

+0

我考慮使用ROWID的唯一目的是在查找表中最近添加的行時獲得更快的性能。 'SELECT MAX(ROWID)FROM transactions'與'SELECT MAX(pk_serial)FROM transactions'。由於我的應用程序是使用INFORMIX-SQL編寫的並且使用了Standadrd Engine(SE),所以ROWID的類型是SERIAL [INT]。新添加的行放在數據文件的末尾。行不會被用戶刪除,但歷史行不會在我的reorg proc中重新加載。即使要刪除行,它們也會被標記但不會被物理刪除,因此它們的ROWID不會被重新分配。 – 2010-06-20 18:40:26

2

嗯,我真的只能告訴它如何工作在Oracle中,用它來19+年:-)

簡單地說,ROWID是個內標識,其作用類似於一個物理地址。它可以分成數據庫文件號,塊號和行號。因此,獲取ROWID使數據庫引擎能夠在單個直接IO中查看數據。

在索引中,B *樹將在葉節點上具有直接指向數據位置的ROWID,例如,在主要索引中。

作爲一個物理地址,它被提交到更改重新定位到磁盤上,這可能發生在恢復備份,重建表或導出/導入數據之後。

數據庫引擎可以做一些技巧,例如,當將可插拔表空間從一個實例移動到另一個實例時,以避免重建索引,但這是嚴格的數據庫引擎內部。

因此,爲了避免麻煩,請將ROWID留在內部用於數據庫引擎。根據自己的用途存儲ROWID最終會導致不一致。