2016-06-07 37 views
1

我找不到在MySQL documentation這在任何地方一個明確的答案。MySQL - 查詢*總是*開始搜索表的開始?

當我運行一個查詢,像這樣:

碼塊1

$stmt = $db->prepare('SELECT id, name FROM table WHERE status=1'); 

確實在表的開始搜索開始,在row 0(或可用的最低行)?

我試圖做的是要經過一次一個表中的一行,然後當我到達終點退出:

代碼塊2

$curRow = 0; 

while(true){ 
    $stmt = $db->prepare('SELECT id, name FROM table WHERE status=? AND id>? LIMIT 1'); 
    $stmt->execute(array(0, $curRow)); 

    $result = $stmt->fetchAll(); 

    if(count($result)){ 
     $curRow = $result[0]['id']; 

     $stmt2 = $db->prepare('UPDATE table SET status=? WHERE id=?'); 
     $stmt2->execute(array(1, $curRow)); 

     ... do some other stuff ... 
    }else{ 
     exit(); 
    } 
} 

等等很遠,在測試中,這完全按照預期工作。但它會一直如此嗎?

可能的錯誤情況:

下表開始了:

table 

id | name | status 
-- | ---- | ------ 
1 | ... | 0 
2 | ... | 0 
3 | ... | 0 
4 | ... | 0 
5 | ... | 0 
6 | ... | 0 

而且在代碼塊2運行查詢。說它開始於第一行,所以現在我們有$curRow=1,並且表如下所示:

table 

id | name | status 
-- | ---- | ------ 
1 | ... | 1 
2 | ... | 0 
3 | ... | 0 
4 | ... | 0 
5 | ... | 0 
6 | ... | 0 

一切都很好。代碼可以做任何需要的事情,然後繼續循環。 剩餘行的任何將滿足條件$stmt(即status=0id>$curRow)。

將把該語句總是看連續的行檢查的條件是什麼時候?如果不是這樣,它可以在任意一行結束了,說第三:

table 

id | name | status 
-- | ---- | ------ 
1 | ... | 1 
2 | ... | 0 
3 | ... | 1 
4 | ... | 0 
5 | ... | 0 
6 | ... | 0 

現在我們必須$curRow=3,這意味着查詢將永遠回去,並期待在第二排。

我知道這是棘手的業務在絕對(永遠,永遠,每一次,...)說,但有什麼辦法,以確保查詢開始在可用的最低行?還是MySQL自動處理?

+2

表格只是一組記錄,不管任何順序。如果您想按特定順序選擇數據,請使用'ORDER BY'。因此,沒有'ORDER BY'子句的'LIMIT'子句沒有多大意義。你只需獲得一張任意選擇的記錄。 –

+0

不依賴於它。取決於正在使用的表類型/引擎,在您選擇的表格上執行更新可能會使選擇的內容無效。 –

+0

根據ANSI SQL標準,沒有保證。訂單上的任何當前觀察到的行爲都可以在不通知版本的情況下更改 –

回答

3

沒有任何可靠的訂單時,你不明確將其設置爲一鍵不能保證。它似乎現在已經下單了,但隨着時間的推移,有了更多的數據,可能會有更多的服務器,分區數據,聯合數據,它會迅速發生意想不到的變化。

更好地利用ORDER BY

$stmt = $db->prepare('SELECT id, name FROM table WHERE status=1 ORDER BY ID ASC'); 

確保您有您想訂購的,它會加快東西列的索引!

1

你不應該寫一個具有數據庫的這樣的假設這樣的代碼。你的代碼可能不易維護,當你的數據庫發生一些變化時,難以進行調試,這對你來說將是一個頭痛的問題。你應該考慮其他機制/解決方法來完成也更專業的工作。

您可能需要添加一個列來提供可以訂購的列。例如日期,ID,無論如何。

查找ORDER BY子句。