1

ネストされたセットを使用して、階層データをMyISAMテーブルに格納しています。テーブルは、ユーザーごとにいくつかの階層セットで構成されています。各ユーザーはそれぞれのツリーに書き込む唯一のユーザーになりますが、他のユーザーはそれらから読み取ることができます。ノードの削除/挿入では、同じツリー内の他の行のlft値とrgt値を更新する必要があり、場合によっては数百行になります。

これを行うには、テーブルの書き込みロックを取得し、ツリー内の他のノードを更新し、行を削除/挿入して、テーブルのロックを解除する必要があります。

私が疑問に思っているのはこれです-テーブルロックは数百人の同時ユーザーに対応できますか?数千?

この場合、InnoDBの行ロックはより効率的でしょうか?(主にユーザー自身のみが使用する数百行をロックします)

行ロックを使用する場合、デッドロックエラーに対処するために明示的なロジックを追加する必要がありますか?

4

1 に答える 1

5

さて、ロックの哲学は2つのエンジン間で異なります。

MyISAMでは、テーブルが完全にロックされる理由は、通常、書き込みが高速である必要があるためです。書き込みに必要な操作は2つだけです(テーブルをロックしてから、行をディスクに書き込みます)。このため、MyISAMのパフォーマンスは実際にはディスク速度によって制限されます。

InnoDBを使用すると、もう少し複雑になります。完全にACIDに準拠しているため、すべての書き込みには4つの手順があります(行のロック、トランザクションログへの書き込み、disへの行の書き込み、トランザクションログへの書き込み)。ディスクに3回書き込むことに注意してください。つまり、(実際には)InnoDBの書き込みにはMyISAMの書き込みの3倍の時間がかかります。これが行レベルのロックの理由の1つです(トランザクションは別です)。

しかし、それはそれほど簡単ではありません。MyISAMでは、テーブルロックにはそのテーブルに1つのセマフォが必要です。したがって、メモリ使用量と速度の両方への影響は、せいぜい取るに足らないものです。ただし、InnoDBでは、行ごとにインデックスと1つのセマフォが必要です。行のロックがすでに存在するかどうかを確認するための「チェック」を高速化するためのインデックスが必要です。これで、1行または10行を同時に更新する場合、ほとんど違いはありません。しかし、何百万もの行について話している場合、その違いは自明ではない可能性があります(ロックされる各行のロック「インデックス」を横切る必要があるため、メモリ使用量と速度の両方で)。

追加のトレードオフもあります。InnoDBはACIDに準拠しているため、電力損失(またはその他のクラッシュ)が発生した場合でも、一貫性のない状態のままになることはありません。データベースにコミットされていないトランザクションのデータはなく、破損したコミットされたトランザクションもありません(修正するものが検出されると、トランザクションログが自動的に実行されます)。MyISAMを使用すると、書き込み中の電力損失(またはクラッシュ)によってテーブルが一貫性のない状態になり、それについて何もできなくなります。データに関心がある場合は、InnoDBの方が適しています。ただし、適切なバイナリログとバックアップシステムを使用すると、MyISAMを回復できるはずですが、手動による介入が必要になります...

さて、そうは言っても、どちらがより良いスケールであるかというあなたの質問は本当に難しいです。まず、あなたの書き込みのほとんどは1行または2行を扱っていますか?その場合、InnoDBと行レベルのロックはより適切にスケーリングする傾向があります。同時に多くの行(数万以上)を更新する多くのクエリを実行すると、MyISAMのパフォーマンスが向上する傾向があることに気付くでしょう。

デッドロックの質問については、MySQLがデッドロックを見つけて処理します(ただし、クエリの1つは実行されないため、例外処理コードでクエリなどを再試行する必要がある場合があります)。内部システムはデッドロックを防ぎます...

さて、別のメモ。MySQLはデータベースで複数のエンジンをサポートしているので、データをInnoDBに入れてから、ネストされたセットデータを処理するためにMyISAM結合テーブルを作成してみませんか?子育て情報をデータテーブルに保存します(parent_idメカニズムを介して)。このように、すべてのデータはACID準拠のデータベースにありますが、ネストされたセットロジックに高速の(読み取りおよび大規模な書き込み用の)MyISAMを使用することで、速度を上げることができます...

于 2010-06-19T12:19:32.210 に答える