2012-05-10 35 views
1

我有一個表(InnoDB),它經常插入,更新和讀取(通常以幾毫秒的間隔)。我注意到,有時INSERT/UPDATE後面的SELECT語句會得到過時的數據。我認爲這是由於緩存,但把SQL_NO_CACHE放在它前面並沒有真正做任何事情。MySQL SQL_NO_CACHE不工作

您如何確保SELECT始終等到先前的INSERT/UPDATE結束並且不從緩存中獲取數據?請注意,這些語句是從單獨的請求中執行的(不在相同的代碼執行中)。

也許我誤解了什麼SQL_NO_CACHE實際上做...

UPDATE

@Uday中,INSERT,SELECT和UPDATE語句看起來如下:

INSERT myTable (id, startTime) VALUES(1234, 123456)

UPDATE myTable SET startTime = 123456 WHERE id = 1234

SELECT SQL_NO_CACHE * FROM myTable ORDER BY startTime

我嘗試使用沒有運氣的事務。

更多更新

我認爲這實際上是插入一個問題,不更新。 SELECT語句總是試圖獲取按時間排序的最新行。但由於INSERT不執行任何表級鎖定,所以SELECT可能會獲取舊數據。有沒有辦法在執行INSERT時強制進行表級鎖定?

+0

您是否會發布SELECT和UPDATEs的樣本... – Uday

+1

您是什麼[isolation level](http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html)使用?如果您使用「READ UNCOMMITTED」或「髒讀」,則可能會發生這種情況。 –

+0

@MarcusAdams無論InnoDB的默認隔離級別是什麼,都不確定是否會回答你的問題。 – pixelfreak

回答

1

查詢緩存不是問題。寫入使緩存無效。

MySQL優先考慮寫入操作並使用默認隔離級別(REPEATABLE READ),您的SELECT將不得不等待UPDATE完成。

如果您爲MyISAM啓用了CONCURRENT INSERTS,INSERT可以以不同方式處理,InnoDB也使用記錄鎖定,因此它不必等待表的插入。

難道這是一個競爭條件呢?你確定你的SELECT是在UPDATE之後發生的嗎?您是否正在從可能更新尚未傳播的複製服務器讀取數據?

如果問題出現在併發INSERT中,您需要在MyISAM上禁用CONCURRENT INSERT,或者在INSERT期間用LOCK TABLES顯式鎖定表。 InnoDB的解決方案是相同的,用LOCK TABLES顯式地鎖定INSERT上的表。

+0

@pixelfreak,我剛剛更新了關於INSERT的回覆。您可能需要使用MyISAM關閉該功能,或使用LOCK TABLES明確鎖定該表。 –

+0

Marcus,我使用的是InnoDB,而不是MyISAM – pixelfreak

+0

@pixelfreak,InnoDB使用記錄鎖定,所以SELECTs不會被表尾處的插入所阻塞。解決方案是一樣的。在插入時使用LOCK TABLES來顯式鎖定表格。對不起,我正在更新我的答案,因爲我也去了,我雖然說你的更新是問題,而不是INSERT。 :) –

0

A)
如果您根本不需要緩存(對於任何SELECT),請完全禁用查詢 緩存。

B)
如果你想這對於只有一個會話,你可以不喜歡它 「設置會話query_cache_type的= 0;」這將爲此設置爲 perticular會話。

另外使用SQL_NO_CAHCE。

+0

1)添加一個像'update'一樣的默認值爲0 2)在更新itslef的同時將其設置爲1。在SELECT中,另外使用「WHERE update = 1」條件。 – Uday