2010-03-25 24 views
2

假設我有一個2列表(id,標誌)和id是連續的。我期望這張表包含大量的記錄。 我想定期選擇未標記的第一行並更新它。路上的一些記錄可能已經被標記,所以我想跳過它們。哪一個是更快/更好的sql練習?

它使更多的意義,如果我儲存的最後一個ID我標記,並在我的SELECT語句中使用它,就像

select * from mytable where id > my_last_id order by id asc limit 1 

或簡單地拿到第一未標記行,如:

select * from mytable where flagged = 'F' order by id asc limit 1 

謝謝!

+0

(可能是拼寫錯誤)「flagged ='F'」是否表示您的記錄已被掛起? – 2010-03-25 12:51:24

+0

好點.. F代表虛假 – artsince 2010-03-25 12:54:26

回答

0

假設MySQL,這一個:

SELECT * 
FROM mytable 
WHERE flagged = 'F' 
ORDER BY 
     flagged ASC, id ASC 
LIMIT 1 

會稍微低效率的InnoDBMyISAM的相同的效率,如果你對(flagged, id)有一個索引。

InnoDB表被聚集在PRIMARY KEY上,因此獲取id中的第一條記錄不需要查找表。

MyISAM中,表是堆組織的,所以用於警告PRIMARY KEY的索引與表分開存儲。

請注意ORDER BY子句中的flagged似乎是多餘的,但MySQL需要選擇正確的索引。

另外,即使在InnoDB(其隱含地將PRIMARY KEY包括到每個索引中),組合索引也應該在(flagged, id)上。

+0

什麼是排序點'標記'因爲它是過濾器(*在結果集*中有一個允許值)...它是沒用的... – 2010-03-25 12:53:14

+0

@Gaby:這將幫助'MySQL'選擇正確的索引。 – Quassnoi 2010-03-25 12:53:50

+0

@Quassnoi,如果它是實現的內在問題,那麼我就宣佈我的無知:)它看起來很不直觀..(編輯:感謝更多信息,現在更有意義:)) – 2010-03-25 12:55:23

2

選項二是唯一有意義的,除非你知道你總是要按順序處理記錄!

+0

我知道我會一直按順序處理它們。 – artsince 2010-03-25 12:49:37

+0

他正在使用一個'訂單由'在密鑰..所以它總是按順序.. – 2010-03-25 12:50:53

+0

@Gaby,我意識到這一點,但沒有什麼說,不能有未經處理的記錄與ID低於「最新處理的ID」。這會讓您在數據中留下空洞,根據第一個查詢的邏輯無法填充數據。 – ninesided 2010-03-25 13:17:17

3

如果您創建了一個標記的索引,檢索一個非標記的行應該是非常即時的操作。如果你總是按順序更新它們,那麼第一種方法很好。

0

你可以使用

Select Min(Id) as 'Id' 
From dbo.myTable 
Where Flagged='F' 

假設被舉報= 'F' 意味着它不標記。

+0

..但他要求'*'不只是身份證.. – 2010-03-25 12:57:40

+0

啊當然是。雖然我不確定爲什麼你會在這種情況下*。 – codingbadger 2010-03-25 13:07:25