1

挿入、更新、読み取りが頻繁に行われるテーブル (InnoDB) があります (通常、数ミリ秒間隔でバーストします)。INSERT/UPDATE に続く SELECT ステートメントが古いデータを取得する場合があることに気付きました。これはキャッシュが原因だとSQL_NO_CACHE思いますが、前に置いた後は実際には何もしません。

前の INSERT/UPDATE が終了するまで SELECT が常に待機し、キャッシュからデータを取得しないようにするにはどうすればよいでしょうか? これらのステートメントは、(同じコード実行内ではなく) 別の要求から実行されることに注意してください。

多分私は SQL_NO_CACHE が実際に何をするのか誤解しています...

更新

@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

運がないトランザクションを使用してみました。

より更新:

これは実際にはUPDATEではなくINSERTの問題だと思います。SELECT ステートメントは常に、時間でソートされた最新の行を取得しようとします。しかし、INSERT はテーブル レベルのロックを行わないため、SELECT が古いデータを取得する可能性があります。INSERT を実行するときにテーブル レベルのロックを強制する方法はありますか?

4

2 に答える 2

1

クエリ キャッシュは問題ではありません。書き込みはキャッシュを無効にします。

MySQL は書き込みを優先し、デフォルトの分離レベル (REPEATABLE READ) では、SELECT は UPDATE が完了するまで待機する必要があります。

MyISAM でCONCURRENT INSERTSを有効にしている場合、INSERT は別の方法で処理できます。また、InnoDB はレコード ロックを使用するため、テーブルの最後で挿入を待つ必要はありません。

これは競合状態になる可能性がありますか?UPDATE の後に SELECT が実行されますか? おそらく更新がまだ反映されていない複製されたサーバーから読んでいますか?

問題が同時 INSERT にある場合は、MyISAM で CONCURRENT INSERT を無効にするか、INSERT 中に LOCK TABLES でテーブルを明示的にロックする必要があります。InnoDB の場合も解決策は同じで、LOCK TABLES を使用して INSERT でテーブルを明示的にロックします。

于 2012-05-10T15:44:09.107 に答える
0

A)
(任意の SELECT に対して) キャッシュがまったく必要ない場合は、クエリ キャッシュを完全に無効にします。

B)
1 つのセッションのみにこれが必要な場合は、「set session query_cache_type=0;」のように実行できます。その特定のセッションに対してこれを設定します。

いずれの場合も、SQL_NO_CAHCE を追加で使用してください。

于 2012-05-10T15:27:15.760 に答える