2010-12-01 11 views
5

テーブルの下に行が挿入される大きなMyISAMテーブルがあります。MyISAMはロックインプロシージャ内の挿入のみを選択します

いくつかのベンチマークを実行している間、私は選択が(常に)同じテーブルへの他の挿入をロックしないことに気付きました。しかし、インサートがストアド・プロシージャ/ファンクションから来るとき、それらはセレクトによってロックされます。

なぜですか?この動作を実証するために

CREATE TABLE Foo (
    ID INT NOT NULL AUTO_INCREMENT, 
    Bar VARCHAR(200), 
    PRIMARY KEY(ID)) ENGINE=MyISAM; 

--INSERT into Foo 10M rows 


DELIMITER $$ 

DROP PROCEDURE IF EXISTS InsertProc$$ 

CREATE PROCEDURE InsertProc(IN vBar VARCHAR(255)) 
BEGIN 
    INSERT Foo(Bar) VALUES (vBar); 
END$$ 

DELIMITER ; 

を実行し、次のクエリ:

SELECT Count(*) FROM Foo WHERE INSTR(Bar, 'abcdefg') > 0; 

選択し、新しい接続を開き、次のINSERTクエリを実行し、実行されていることながら:

INSERT Foo(Bar) VALUES ('xyz1234'); 

その挿入物はすぐに実行されて戻りますが、次のクエリを実行すると:

CALL InsertProc('xyz1234'); 

これで、クエリはロックされ、選択が完了するのを待ちます。

MySQLバージョン:5.0.51が

ありがとうウィンドウサーバー2K3上で実行されています。

挿入ダイレクト:手順を経由して

(initialization)  0.0000432 
checking permissions 0.0000074 
Opening tables  0.0000077 
System lock   0.0000032 
Table lock   0.0000025 
init     0.000021 
update    0.0002365 
end     0.0000382 
query end   0.000002 
freeing items  0.0000057 
closing tables  0.0000022 
logging slow query 0.0000005 

インサート: -

UPDATEここ は、プロファイル出力である

(initialization) 0.0000285 
Opening tables 0.0004325 
System lock  0.0000022 
Table lock  0.0002957 
checking permissions 0.0000047 
Opening tables 0.000004 
System lock  0.0000017 
Table lock  3.2365122 
init    0.0000422 
update   0.000251 
end    0.0000025 
query end  0.000003 
closing tables 0.00004 
query end  0.0000074 
freeing items 0.0000074 
logging slow query 0.000001 
cleaning up  0.5790915 

なぜ手順オープンし、二回 "表ロック" ?

+0

私はこの質問に報奨金を追加するにはどうすればよい、この辺りに新しいのですか? –

+0

これが特定の問題を引き起こしているかどうかもっと説明できますか? – zanlok

+0

@ zanlok、問題は、コードをDBのストアドプロシージャからアプリケーションに移動する必要があることです。このロック問題を回避する手段がない限り、 –

答えて

1

MyIASMは何か特別な理由がありますか? InnoDBテーブルは通常、より良いロック特性を持っています。

+0

はい、それは重い表を書くことです。私たちはMyISAM –

0

推測:ストアドプロシージャを使用すると、おそらくMyISAMテーブルのAUTO_INCREMENTフィールドのロック/ミューテックス処理が厳しくなります。

IDAUTO_INCREMENTフィールドではないテストを設定することはできますか?

INSERT DELAYEDは、アプリケーションで許可されている場合に試しましたか?

+0

を使ってパフォーマンスを向上させていますが、AUTO_INCREMENTを削除することは役に立ちません。 INSERT DELAYEDは私たちのためには機能しません。 –

関連する問題