2

3つのテーブルに1500万行あります(1つのテーブルは元のCSVインポートであり、他の2つはそのCSVの正規化バージョンとその他のデータです)。

元のCSVテーブルから1つのフィールドを更新するだけです。これらのテーブルを結合する更新クエリは、クアッドコア-8GB-ssdボックスで30時間実行されました。

  • これは正常ですか?この簡単な更新を実行するためのより良い方法はありますか?

Tables: ti (the CSV dump, denormalized, ~13M rows)
        i (the primary, normalized table, ~17M rows)
        icm (a map of ti.raw_id to i.item_id, ~17M rows)

mysql> explain select * from item AS i, item_catalog_map AS icm, temp_input AS ti WHERE i.id=icm.item_id AND icm.catalog_unique_item_id=ti.productID;
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
| id | select_type | table | type   | possible_keys        | key                  | key_len | ref        | rows     | Extra       |
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
|  1 | SIMPLE      | i     | ALL    | PRIMARY              | NULL                 | NULL    | NULL       | 13652592 |             |
|  1 | SIMPLE      | icm   | ref    | IDX_ACD6184F126F525E | IDX_ACD6184F126F525E | 5       | frugg.i.id |        1 | Using where |
|  1 | SIMPLE      | ti    | eq_ref | PRIMARY              | PRIMARY              | 767     | func       |        1 | Using where |
+----+-------------+-------+--------+----------------------+----------------------+---------+------------+----------+-------------+
3 rows in set (0.06 sec)

mysql> UPDATE item AS i, item_catalog_map AS icm, temp_input AS ti
    -> SET i.name=ti.productName,
    ->     icm.price=ti.retailPrice,
    ->     icm.conversion_url=productURL
    -> WHERE i.id=icm.item_id AND icm.catalog_unique_item_id=ti.productID;
4

1 に答える 1

1

まず、非正規化されたデータに13Mのレコードがあり、両方の「正規化された」テーブルに17Mのレコードがある場合、正規化からあまり圧縮されていません。

次に、1つのSQLステートメントで両方の正規化されたテーブルを更新しようとしています。最初にマッピングテーブルを更新してから、2番目のSQLステートメントでデータテーブルを更新する必要があると思います。

第3に、内部結合を実行すると、クエリが3方向デカルト積を実行するため、処理が高速化される可能性があります。正確には言えませんが、あなたは古い学校に参加しているだけで、オプティマイザはそれを取得する必要がありますが、それでもJOIN構文を使用します。

UPDATE item_catalog_map AS icm
       INNER JOiN temp_input AS ti
          ON icm.catalog_unique_item_id = ti.productID
  SET icm.price = ti.retailPrice,
      icm.conversion_url = productURL;


UPDATE item AS i
       INNER JOIN temp_input AS ti
          ON i.id = icm.item_id
  SET i.name = ti.productName;

最後に、あなたが持っていることを確認するためのインデックスは次のとおりです。

CREATE INDEX IDX_CATALOG ON item_catalog_map (catalog_unique_item_id);
CREATE INDEX IDX_RAW_PRODUCT_ID ON temp_input (productID);
CREATE INDEX IDX_RAW_ITEM_ID ON temp_input (item_id);
于 2012-10-09T12:32:16.093 に答える