5

ODBCと接続しているクライアントアプリケーションにキーの長いリストがある場合、MySqlの多くの行を操作するための良い方法は何ですか?

注:私の経験は主にSQL Serverであるため、MySQLだけでなく、少しは知っています。

タスクは9つのテーブルからいくつかの行を削除することですが、5,000以上のキーペアがある可能性があります。

私は、すべてのキーをループして、各テーブルに対して各キーのステートメントを送信する簡単な方法から始めました。たとえば、次のようになります。

DELETE FROM Table WHERE Key1 = 123 AND Key2 = 567 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 124 AND Key2 = 568 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 125 AND Key2 = 569 -- and 8 more tables
...

ただし、それは45,000の個別のステートメントになりますが、ご想像のとおり、少し遅いです。

では、フロントエンドで使用しているプログラミング言語を気にせずに、リストを送信して、一度に、または少なくとも大量に操作を実行できるようにするための良い方法は何でしょうか。これまでの私の考えは次のとおりです。

  • 一時テーブルを作成して挿入し、結合します。MySQLの構文を調べて一時テーブルを作成しますが、それは良い方法ですか?

  • 一時テーブルを使用すると仮定すると、一時テーブルにデータを入力するための最良の方法は何ですか?5000INSERT Table VALUES ()ステートメント?SELECT 123, 456 UNION ALL SELECT 124, 457?MySqlがテーブルに対して発行されないこの種のSELECTを許可することをテストしました。しかし、リストが長くなりすぎるとSQL Serverが最終的に爆発するので、これはMySQLの良い方法ですか?リストを一度に数百に保つ必要がありますか?

    --CREATE Temp Table ( I do not know the syntax in MySql yet)
    
    INSERT INTO TempTable
    SELECT 123, 456
    UNION ALL SELECT 124, 457
    UNION ALL SELECT 125, 458
    
    DELETE T
    FROM
       Table T
       INNER JOIN TempTable X ON T.Key1 = X.Key1 AND T.Key2 = X.Key2
    
  • XML。MySQL 5.1にはいくつかのXML関数があるようですが、大まかな検索では、XMLテキストのチャンクを結合する行セットに変換することをサポートしていないようです。本当?値をXMLに取り込むのは非常に簡単です。

  • 仮想分割操作。MySqlには、ある種の手続き型言語が可能であると思います。SQL Serverでは、文字列を解析して行セットに変換するカスタムコードを記述できます。

    CREATE PROCEDURE DoStuff @KeyString varchar(max)
    AS
    DECLARE @Keys TABLE (
       Key1 int,
       Key2 int,
       PRIMARY KEY CLUSTERED (Key1, Key2)
    )
    DECLARE @Pos int
    WHILE @Pos < Len(@KeyString) BEGIN
       -- loop to search for delimiting commas in @KeyString
       -- and insert pairs of parsed tokens to table variable @Keys
    END
    
    DELETE T
    FROM
       Table T
       INNER JOIN @Keys K ON T.Key1 = K.Key1 AND T.Key2 = K.Key2
    

私はMySQLに慣れていないので、最初に調査する可能性が本当にわかりません。悪い決断をしたり、難しい方法を学んだりするのを防ぐために、助けていただければ幸いです。

4

1 に答える 1

2

一時テーブルソリューションを使用して、DELETEステートメントの各メインテーブルに結合します。したがって、テーブルごとに1つずつ、合計9つの削除を実行するだけで済みます。

  • CREATE TEMPORARY TABLE

    CREATE TEMPORARY TABLE Keys (
        Key1 INT UNSIGNED NOT NULL, 
        Key2 INT UNSIGNED NOT NULL, 
        PRIMARY KEY(Key1, Key2)
    );
    
  • を使用して、タブ区切りデータのファイルを一時テーブルにロードします。LOAD DATA LOCAL INFILE

    LOAD DATA LOCAL INFILE 'C:/path/to/datafile' INTO TABLE Keys;
    
  • MySQLのマルチテーブルDELETE構文を使用して削除します。

    DELETE t FROM Table1 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table2 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table3 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table4 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table5 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table6 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table7 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table8 t JOIN Keys USING (Key1, Key2);
    DELETE t FROM Table9 t JOIN Keys USING (Key1, Key2);
    

コメントを再確認してください。

MySQLのドキュメントにCREATE TABLEは次のように書かれています。

TEMPORARYテーブルは現在の接続にのみ表示され、接続が閉じられると自動的に削除されます。これは、2つの異なる接続が、互いに競合したり、同じ名前の既存の非TEMPORARYテーブルと競合したりすることなく、同じ一時テーブル名を使用できることを意味します。(既存のテーブルは、一時テーブルが削除されるまで非表示になります。)

それはかなり明確です!

データのロードに関しては、で行うことができますINSERT。5000行は大したことではありません。PHPスクリプトを使用して数百万行(StackOverflow XMLデータダンプなど)をMySQLにロードしますが、これには約20分しかかかりません。プリペアドステートメントを使用して、パラメーターを使用して実行します。

于 2010-02-12T18:42:25.277 に答える