2009-01-12 21 views
2

我有一個非常慢的查詢,我需要不時在MySQL數據庫上運行。如果您嘗試更新正在查詢的表,MySQL會執行什麼操作?

我發現嘗試更新正在查詢的表將被阻止,直到查詢完成。

我想這是有道理的,否則查詢的結果可能不一致,但對我來說並不理想,因爲查詢的重要性比更新低得多。

所以我的問題真的有兩個部分:

  1. 出於好奇,究竟是什麼做的MySQL在這種情況呢?它是否在查詢期間鎖定表格?或者嘗試在更新之前鎖定它?

  2. 有沒有辦法讓慢查詢不阻塞?我想這些選項可能是:

    • 當需要更新時終止查詢。
    • 在更新發生之前對錶的副本運行查詢
    • 只讓查詢出錯。

任何人有什麼想法?

回答

5

這聽起來像你正在使用MyISAM表,它使用表級鎖定。在這種情況下,SELECT將在表上設置一個共享鎖。然後,UPDATE將嘗試請求排它鎖和塊,並等待SELECT完成。一旦完成,UPDATE將像正常一樣運行。

MyISAM Locking

如果您切換到InnoDB的,那麼你的選擇將默認設置沒有鎖。不需要像其他人推薦的那樣更改事務隔離級別(InnoDB的可重複讀取默認值,您的SELECT不會設置鎖)。 UPDATE將能夠同時運行。 InnoDB使用的多版本與Oracle處理這種情況非常相似。 SELECTs設置鎖定的唯一時間是如果您運行在可序列化的事務隔離級別中,那麼對查詢有一個FOR UPDATE/LOCK IN SHARE MODE選項,或者它是某種寫入語句(如INSERT的一部分)。 ..SELECT)並且您正在使用基於語句的二進制日誌記錄。

InnoDB Locking

0

我不知道MySQL,但它聽起來像事務問題。 您應該能夠在您的選擇查詢中將事務類型設置爲髒讀。

這並不總是給你正確的結果。但它不應該被阻止。

更好的辦法是讓第一個查詢更快。做一些分析,並檢查是否可以通過正確的縮進等來加速它。

0

UPDATE LOW_PRIORITY ....可能會有所幫助 - mysql文檔不清楚這是否會讓用戶請求更新繼續,更新是在可能時發生(這是我認爲會發生的情況)還是用戶必須等待(這會比現在更糟糕......),我不記得了。

您使用的是哪種表格類型?如果你在MyISAM上,切換到InnoDB(如果可以的話 - 它沒有全文索引)爲這類事情開闢了更多的選擇,因爲它支持事務特性和行級鎖定。

+0

謝謝。不幸的是,我被困在MyISAM中......否則,聽起來像切換到InnoDB將是答案... – Ben 2009-01-12 15:23:48

+0

UPDATE LOW_PRIORITY不允許UPDATE與SELECT相同。它在決定下一次要授予的鎖定時與排隊順序有關。 – 2009-01-12 15:57:00

1

SELECT語句的目的,你應該發出:連接,這將導致隨後的SELECT語句無鎖定操作上
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
命令。
請勿使用'SELECT ... FOR UPDATE',因爲這肯定會鎖定受select語句影響的錶行。
msql事務分區級別的完整列表是in the docs

1

首先你需要知道你使用的是什麼引擎(MySam或InnoDb)。

這顯然是一個交易問題。

看一看13.4.6。 SET TRANSACTION語法在mysql手冊中。

相關問題