我有如下表:SQLite的:大規模更新場而不光標
CREATE TABLE Records (
RecordIndex INTEGER NOT NULL,
...
Some other fields
...
Status1 INTEGER NOT NULL,
Status2 INTEGER NOT NULL,
UpdateDate DATETIME NOT NULL,
CONSTRAINT PK_Records PRIMARY KEY (RecordIndex ASC))
和索引:
CREATE INDEX IDX_Records_Status ON ClientRecords
(Status1 ASC, Status2 ASC, RecordIndex ASC)
我需要逐個獲取的一定地位的記錄,所以我用這個語句:
SELECT *
FROM RECORDS
WHERE RecordIndex > @PreviousIndex
AND Status1 = @Status1
AND Status2 = @Status2
LIMIT 1
但現在我需要獲取由另一個字段排序的記錄,但該字段不爲每個記錄獨特的,所以我不能以相同的方式使用它。所以我決定在我的表格中添加一個新的SortIndex字段。
由於SQLite中沒有遊標,我正在執行以下操作以初始化SortIndex的值。
首先,我創建一個臨時表:
CREATE TEMP TABLE Sort (
SortIdx INTEGER PRIMARY KEY AUTOINCREMENT,
RecordIdx INTEGER)
然後我填這個表中正確排序順序:
INSERT INTO Sort
SELECT NULL, RecordIndex
FROM Records
ORDER BY SomeField ASC, RecordIndex ASC
然後,我創建臨時表上的索引:
CREATE INDEX IDX_Sort_RecordIdx ON Sort (RecordIdx ASC)
然後我更新我的Records表中的SortIndex字段:
UPDATE Records
SET SortIndex =
(SELECT SortIdx
FROM Sort
WHERE RecordIdx = RecordIndex)
然後我把臨時表:
DROP TABLE Sort
而且finaly我在我的記錄表上創建新的索引
CREATE INDEX IDX_Records_Sort ON Records
(Status1 ASC, Status2 ASC, SortIndex ASC)
這讓我做了以下選擇
SELECT *
FROM Records
WHERE SortIndex > @PreviousSortIndex
AND Status1 = @Status1
AND Status2 = @Status2
LIMIT 1
問題是,由於表格包含大約500K條記錄,整個事情大約需要2分鐘。它很可能已經快了很多與遊標初始化SortIndex,但SQLite的缺乏這種功能:(
有一個更快的方法來做到這一點?
提前感謝!
首先,索引IDX_Records_Sort不是動態的。該表被填充一次,以後不再添加任何記錄,因此SortIndex字段只需要「計算」一次,並且索引是在填充表後立即創建的。其次,選擇「SELECT * FROM Records WHERE Status1 = @ Status1 AND Status2 = @ Status2 ORDER BY SomeField ASC,ClientIndex ASC LIMIT 1 OFFSET @PreviousIndex」將不起作用,因爲兩種狀態都可以更改,在這種情況下,偏移量不會再正確無誤。 – Marc 2011-05-11 07:10:56
@Marc,這個官方化發生的頻率如何?什麼意思是「一次」? 你也可以描述你的奇怪的邏輯:爲什麼在閱讀過程中可能會發生變化? – gaRex 2011-05-11 08:01:21
@Alexander,表格填充一次,使用批量插入,除2個狀態字段外,大多數字段不會更改(包括用於排序的字段)。用戶希望按照排序字段的順序在屏幕上查看具有特定狀態的記錄。他將依次審查每條記錄並最終更新狀態。然後他會顯示「下一個」記錄。因此,儘管他通過2個狀態值選擇了一條記錄,但他可以在選擇下一條記錄之前更新狀態值。這就是爲什麼偏移方法不起作用。謝謝。 – Marc 2011-05-11 09:07:41