[はじめに] MySQL では、ステートメントのスケジューリング特性に影響を与えることができます。これにより、複数のクライアントからのクエリがより適切に連携し、単一のクライアントが長時間ロックされないようになります。スケジューリング特性を変更すると、特定のクエリがより速く処理されるようにすることもできます。まず MySQL のデフォルトのスケジューリング ポリシーを見て、次に
を見てみましょう。MySQL では、ステートメントのスケジューリング特性に影響を与えることができます。これにより、複数のクライアントからのクエリがより適切に連携し、単一のクライアントが長時間ロックアウトされることがなくなります。長い間。スケジューリング特性を変更すると、特定のクエリがより速く処理されるようにすることもできます。まず MySQL のデフォルトのスケジューリング ポリシーを見て、次にこのポリシーを変更するためにどのようなオプションが利用できるかを見てみましょう。この説明では、検索 (SELECT) を実行するクライアント プログラムがリーダー プログラムであると仮定します。テーブル変更操作 (DELETE、INSERT、REPLACE、または UP DATE) を実行する別のクライアント プログラムがライターです。
MySQL の基本的なスケジューリング戦略は次のように要約できます:
◆書き込みリクエストは到着した順に処理される必要があります。
◆書くことは読むことよりも優先されます。
テーブルロックを利用してスケジューリング戦略を実装します。クライアント プログラムがテーブルにアクセスする場合は、まずテーブルのロックを取得する必要があります。これは、LOCK TABLES を使用して直接実行できますが、通常は、サーバーのロック マネージャーが必要に応じて自動的にロックを取得します。テーブルのロックは、クライアントがテーブルの処理を終了すると解放できます。直接取得したロックは UNLOCK TABLES で解放できますが、サーバーは取得したロックも自動的に解放します。
書き込み操作を実行するクライアントは、テーブルに対して排他的アクセスロックを持っている必要があります。書き込み操作の進行中は、テーブル上のデータ レコードが削除、追加、または変更されるため、テーブルは不整合な状態になり、それに応じてテーブルのインデックスも更新する必要がある場合があります。テーブルが常に変更されている場合、現時点で他のクライアントにテーブルへのアクセスを許可すると問題が発生する可能性があります。 2 つのクライアントが同時に同じテーブルに書き込むことは明らかに良くありません。テーブルがすぐに使用できなくなるからです。また、クライアントが変更中のテーブルを読み取ることを許可することも良いことではありません。テーブルを読み取った時点でテーブルに変更が加えられている可能性があり、結果が不正確になるためです。読み取り操作を実行するクライアントには、テーブルの読み取りプロセス中にテーブルが変更されないように、他のクライアントがテーブルに書き込むことを防ぐロックが必要です。ただし、ロックは読み取り操作に対する排他的アクセスを提供する必要はありません。このロックにより、他のクライアントが同時にテーブルから読み取ることもできます。読み取りによってテーブルは変更されないため、他のクライアントによるテーブルの読み取りを妨げる必要はありません。
MySQL では、いくつかのクエリ制限修飾子がそのスケジューリング戦略に影響を与えることができます。そのうちの 1 つは、DELETE、INSERT、LOAD DATA、REPLACE、および UP DATE ステートメントの LOW_PRIORITY キーワードです。もう 1 つは、SELECT ステートメントの HIGH_PRIORITY キーワードです。 3 番目は、INSERT ステートメントと REPLACE ステートメントの DELAYED キーワードです。
LOW_PRIORITYキーワードは、次のようにスケジューリングに影響します。通常、テーブルの読み取り中にテーブルへの書き込みが到着した場合、クエリが開始されると中断できないため、ライターはリーダーが完了するまでブロックされます。ライターの待機中に別の読み取り要求が到着すると、デフォルトのスケジューリング ポリシーによりライターにリーダーよりも高い優先順位が与えられるため、リーダーもブロックされます。第1の読み出しプログラムの終了後、書き込みプログラムが継続し、この書き込みプログラムの終了後に第2の読み出しプログラムが開始される。
書き込みリクエストが LOW_PRIORITY リクエストの場合、書き込み操作は読み取り操作よりも高い優先順位を持つとは見なされません。この場合、ライターの待機中に 2 番目の読み取り要求が到着した場合は、2 番目の読み取り操作を待機中の書き込み操作の前にキューに入れます。ライターは、他の読み取りリクエストがない場合にのみ実行を許可されます。スケジューリングにおけるこの変更の理論的な意味は、LOW_PRIORITY 書き込みが永久にブロックされる可能性があるということです。前の読み取りリクエストの処理中に別の読み取りリクエストが到着すると、この新しいリクエストは LOW_PRIORITY 書き込みの前にキューに入れられます。
SELECTクエリのHIGH_PRIORITYキーワードも同様の効果があります。これにより、書き込み操作が通常の優先順位を持っている場合でも、保留中の書き込み操作の前に SELECT が挿入されます。 INSERT の ELAYED 修飾子は次のように機能します。テーブルに対する INSERT DELAYED リクエストが到着すると、サーバーは対応する行をキューに入れ、クライアント プログラムが実行を継続できるように直ちにステータスを返します。 rows まだテーブルに挿入されていません。リーダーがテーブルから読み取りを行っている場合、キュー内の行は保留中になります。読み取りがない場合、サーバーは遅延行キューへの行の挿入を開始します。サーバーは時々停止して、新しい読み取りリクエストが到着したかどうかを確認し、待機します。そうである場合、遅延行キューは一時停止され、リーダーは続行できます。他に読み取り操作がない場合、サーバーは遅延行の挿入を再び開始します。このプロセスは、遅延キューが空になるまで継続します。
これは、すべての MySQL バージョンに表示されるわけではありません。次の表に、これらの修飾子とそれらをサポートする MySQL バージョンを示します。この表を使用して、使用している MySQL バージョンにどのような機能があるかを判断できます:
INSERT DELAYED は、他のクライアントが長い SELECT ステートメントを実行する可能性があり、挿入が完了するまで待ちたくない場合に便利です。 INSERT DELAYED を発行するクライアントは、サーバーが挿入対象の行を挿入するだけなので、より迅速に実行を続行できます。ただし、通常の INSERT と INSERT DELAYED のパフォーマンスの違いに注意する必要があります。 INSERT DELAYED に構文エラーがある場合、クライアントにエラーが送信され、正常であればメッセージは送信されません。たとえば、このステートメントが返されたときに取得される AUTO_INCREMENT 値は信頼できません。また、一意のインデックスの重複の数を取得することもできません。これは、挿入操作が実際の挿入が完了する前にステータスを返すために発生します。また、INSERT DELAYED ステートメントの行が挿入待ちのキューに入れられ、サーバーがクラッシュするか (kill -9 で) 終了される場合、これらの行は失われることを示す人もいます。通常の TERM 終了ではこれは行われません。サーバーは終了する前にこれらの行を挿入します。
上記は、MySQL の基本的なスケジューリング戦略の簡単な分析です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。