無料PHPプログラム

MySQL 5.1 リファレンスマニュアル :: 6 最適化 :: 6.2 SELECTステートメントおよびその他のクエリの最適化 :: 6.2.16 INSERTステートメントの速度
« 6.2.15 テーブルスキャンを避ける方法

6.2.17 UPDATEステートメントの速度 »
Section Navigation      [Toggle]
  • 6.2 SELECTステートメントおよびその他のクエリの最適化
  • 6.2.1 EXPLAINを使用して、クエリを最適化する
  • 6.2.2 クエリパフォーマンスの推定
  • 6.2.3 SELECTクエリの速度
  • 6.2.4 WHERE 節最適化
  • 6.2.5 Range 最適化
  • 6.2.6 インデックス結合最適化
  • 6.2.7 IS NULL最適化
  • 6.2.8 DISTINCT最適化
  • 6.2.9 LEFT JOINとRIGHT JOIN最適化
  • 6.2.10 入れ子結合最適化
  • 6.2.11 外側Join 単純化
  • 6.2.12 ORDER BY最適化
  • 6.2.13 GROUP BY最適化
  • 6.2.14 LIMITの最適化
  • 6.2.15 テーブルスキャンを避ける方法
  • 6.2.16 INSERTステートメントの速度
  • 6.2.17 UPDATEステートメントの速度
  • 6.2.18 DELETEステートメントの速度
  • 6.2.19 その他の最適化のヒント

6.2.16. INSERTステートメントの速度

行挿入の時間は、以下の要因によって決定されます。(数はおよその割合を示します。)

  • 接続: (3)

  • サーバへのクエリの送信: (2)

  • クエリの解析: (2)

  • 行挿入:(1 × 行サイズ)

  • エンデックス挿入:(1 × インデックス数)

  • クローズ: (1)

テーブルを開く初期オーバヘッドは算入されていません(これは同時実行クエリのそれぞれで 1 回実行されます)。

テーブルのサイズによって対数Nの分だけインデックス挿入の速度が低下します(B ツリー)。

挿入の速度を上げる方法

  • 1 つのクライアントから同時に多数の行を挿入する場合は、マルチプルVALUESリストでINSERTステートメントを使用します。これで独立した INSERT ステートメントの使用時と比較して大幅に(場合によっては数倍)速度が上がります。空ではないテーブルにデータを追加する場合は、さらに速度を上げるためにbulk_insert_buffer_size 変数を調整します。項4.2.3. 「システム変数」を参照してください。

  • 異なる複数のクライアントから大量のレコードを挿入する場合は、INSERT DELAYEDステートメントを使用すると速度を上げることができます。項12.2.4.2. 「INSERT DELAYED 構文」を参照してください。

  • MyISAM テーブルでは、テーブルに削除された行がない場合、SELECTの実行と同時に行を挿入できることに注意してください。項6.3.3. 「同時挿入」を参照してください。

  • テキストファイルからテーブルをロードする場合は LOAD DATA INFILEを使用します。通常、これは INSERTステートメントを使用する場合と比較して、20 倍速度が上がります。項12.2.5. 「LOAD DATA INFILE 構文」を参照してください。

  • テーブルにインデックスが多数ある場合、操作を少し追加するだけでMyISAMテーブルのLOAD DATA INFILE の実行速度をさらに上げることができます。以下の手順を使用してください。

    1. CREATE TABLEを使用して、テーブルを作成します。

    2. FLUSH TABLESステートメントまたはmysqladmin flush-tablesコマンドを実行します。

    3. myisamchk --keys-used=0 -rq /path/to/db/tbl_nameを使用します。これでテーブルからすべてのインデックスの使用が削除されます。

    4. LOAD DATA INFILEを使用して、テーブルにデータを挿入します。これはインデックスをまったく更新しないため、非常に高速になります。

    5. テーブルを読み取り専用にする場合は、myisampackを実行してテーブルを小さくします。項13.4.3.3. 「圧縮テーブルの特徴」を参照してください。

    6. myisamchk -rq /path/to/db/tbl_nameを使用してインデックスを作成しなおします。これは、ディスクに書き込む前にメモリにインデックスツリーを作成してディスクシークを回避するため、LOAD DATA INFILE中のインデックス更新が非常に高速になります。生成されたインデックスツリーは完全にバランスが取られています。

    7. FLUSH TABLESステートメントまたはmysqladmin flush-tablesコマンドを実行します。

    データを挿入したMyISAMテーブルが空の場合は、LOAD DATA INFILEは上記の最適化を自動的に実行します。上記手順との主な相違点は、LOAD DATA INFILEステートメントの実行中にサーバにインデックスの再作成を割り当てる場合より、myisamchkにインデックス作成用のテンポラリメモリ割り当てるほうが、より大幅に割り当てることができる点です。

    myisamchkよりも以下のステートメントを使用して、MyISAMのインデックス利用を可能にしたり、不可能にしたりできます。これらのステートメントを使用すると、FLUSH TABLEオペレーションをスキップできます。

    ALTER TABLE tbl_name DISABLE KEYS;
    ALTER TABLE tbl_name ENABLE KEYS;
    
  • 非トランザクショナルテーブル上で、複数ステートメントを使用して実行されるINSERT速度を上げるには、テーブルをロックしてください。

    LOCK TABLES a WRITE;
    INSERT INTO a VALUES (1,23),(2,34),(4,33);
    INSERT INTO a VALUES (8,26),(6,29);
    ...
    UNLOCK TABLES;
    

    主な速度の相違点は、すべての INSERT ステートメントの完了後にインデックスバッファが 1 回のみディスクにフラッシュされることです。通常は、INSERT ステートメントの数と同じだけ、インデックスバッファのフラッシュが行われます。すべての行を 1 つのINSERTで挿入できる場合はロックの必要がありません。

    トランザクショナルテーブルの場合は、LOCK TABLESではなく START TRANSACTIONおよびCOMMIT を使用して速度の改善を図ります。

    ロックは複数の同時接続テストの合計時間も短縮するが、一部のスレッドの最大待機時間は長くなります。(ロックの際に待機するため)例 :

    1. 接続1は1000行を挿入

    2. 接続2, 3,4は1行を挿入

    3. 接続5は1000行を挿入

    ロックを使用しない場合、2、3、4 は 1 と 5 の前に終了します。ロックを使用した場合は、2、3、4 は 1 と 5 の前には終了しない確率が高くなりますが、合計時間は約 40% 短縮されます。

    MySQL では、INSERT、UPDATE、および DELETEの演算が非常に速いため、約 5 つより多い挿入や 更新をする前にロックを追加すると、総合的なパフォーマンスを改善できます。1 行で非常に多数の挿入を実行する場合は、ときどき(約 1,000 行ごと)LOCK TABLESにUNLOCK TABLES を続けて実行して、他のスレッドからのテーブルへのアクセスを可能にすることができます。これでもパフォーマンの増加が得られます。

    アウトラインストラテジー使用時でも、データのロードにはLOAD DATA INFILEのほうがINSERTよりも大幅に高速です。

  • MyISAMテーブルおよびLOAD DATA INFILEとINSERTの両方に対するパフォーマンスの向上には、key_buffer_sizeシステム変数値を上げてキーキャッシュを拡張します。項6.5.2. 「サーバパラメータのチューニング」を参照してください。

MySQL Enterprise.? サーバのパフォーマンスを最適化するための詳しいアドバイスについては、MySQL Network Monitoring and Advisory Serviceを購読してください。多数のアドバイザーがパフォーマンス向上をサポートします。追加情報については http://www-jp.mysql.com/products/enterprise/advisors.htmlを参照してください。

Copyright c 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates

無料CGI PHPスクリプト | 新着情報スクリプト | 営業日カレンダー | PHPマニュアル | MySQLマニュアル | PEARマニュアル

Copyright (c) 2010 jmcodex.com All rights reserved.