web-dev-qa-db-ja.com

MySQLでロックを発生させずに選択する方法はありますか?

クエリ:

SELECT COUNT(online.account_id) cnt from online;

ただし、オンラインテーブルもイベントによって変更されるため、show processlistを実行するとロックが頻繁に表示されます。

MySQLに、ロックを引き起こさないselectステートメントを作成できる文法はありますか?

そして、MySQLスレーブデータベース上にあることを上記で言及するのを忘れました。

my.cnf:transaction-isolation = READ-UNCOMMITTEDに追加した後、スレーブはエラーに遭遇します。

エラー 'バイナリロギングはできません。メッセージ:InnoDBのトランザクションレベル「READ-UNCOMMITTED」は、クエリのbinlogモード「STATEMENT」に対して安全ではありません

だから、これを行うための互換性のある方法はありますか?

119
omg

「MYSQL WITH NOLOCK」というタイトルの記事を見つけました

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

mS SQL Serverでは、次のことを行います。

SELECT * FROM TABLE_NAME WITH (nolock)

mYSQLと同等のものは

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;

編集

Michael Mior は以下を提案しました(コメントから)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;
157
Jon Erickson

テーブルがInnoDBの場合は、 http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html を参照してください-一貫した読み取りを使用します(ロックなし)モード)SELECT.

23
Alex Martelli

つかいます

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

バージョン5.0のドキュメントは こちら です。

バージョン5.1ドキュメントは here です。

16
NotMe

MySQLマニュアルの このページ を読むことをお勧めします。テーブルがロックされる方法は、テーブルの種類によって異なります。

MyISAMはテーブルロックを使用して非常に高い読み取り速度を実現しますが、UPDATEステートメントが待機している場合、今後のSELECTSはUPDATEの背後でキューに入れられます。

InnoDBテーブルは行レベルのロックを使用し、テーブル全体がUPDATEの背後でロックされることはありません。 InnoDBには他の種類のロックの問題が関連付けられていますが、ニーズに合っている場合があります。

13
zombat

テーブルのタイプに応じて、ロックの実行方法は異なりますが、SELECTカウントも同様です。 MyISAMテーブルの場合、レコード数を取得するためにメタデータにアクセスするため、単純なSELECT count(*)FROMテーブルはテーブルをロックしません。 Innodbは、レコードをカウントするためにスナップショットでテーブルを取得する必要があるため、時間がかかりますが、ロックは発生しません。

少なくとも、concurrent_insertを1(デフォルト)に設定する必要があります。次に、データファイルに入力するテーブルの「ギャップ」がない場合、挿入がファイルに追加され、MyISAMテーブルでSELECTとINSERTが同時に発生する可能性があります。レコードを削除すると、データファイルに「ギャップ」が生じ、将来の挿入と更新で埋められるようになります。

まれにレコードを削除する場合は、concurrent_insertを2に設定することができ、挿入は常にデータファイルの最後に追加されます。その後、選択と挿入を同時に行うことができますが、削除するレコードの数(すべてのレコードを除く)に関係なく、データファイルが小さくなることはありません。

結論として、テーブルで多くの更新、挿入、選択を行う場合は、InnoDBにする必要があります。ただし、システム内でテーブルタイプを自由に混在させることができます。

2
Brent Baisley

SELECTは通常、InnoDBテーブルで気にするロックを行いません。デフォルトのトランザクション分離レベルは、「ロックしない」を選択することを意味します。

もちろん、まだ競合が発生しています。

0
MarkR

mysqlでダーティリードを有効にする別の方法は、ヒントを追加することです:LOCK IN SHARE MODE

SELECT * FROM TABLE_NAME LOCK IN SHARE MODE; 
0
PuGong

this リファレンスから:

LOCK TABLESを使用して明示的にテーブルロックを取得する場合、テーブルがロックされている間に他のセッションが同時挿入を実行できるように、READロックではなくREAD LOCALロックを要求できます。

0
Paul Sonier