1

結合を使用して別のテーブルのフィールドに基づいてフィールドを更新しようとしています:

UPDATE transactions
JOIN products ON products.link = transactions.product_id 
SET transactions.user_id = products.user_id
WHERE transactions.user_id != products.user_id

ただし、これには非常に長い時間がかかります (15 分以上)。Products には 10,000 行、transactions には約 90,000 行あります。クエリを最適化できる方法はありますか?

トランザクション テーブル:

id              int(11)
transaction_id  varchar(255)
user_id         int(11)
product_id      varchar(50)

製品表:

id      int(11)
user_id int(11)
link    varchar(45)
4

4 に答える 4

1

ここには2つの問題があります

  1. Products テーブルと Transactions テーブルは、異なるサイズの Varchar フィールドを介してリンクされています。これにより、クエリ オプティマイザーが両方のテーブルをスキャンするように強制されます (どちらにもインデックスが作成されていないと仮定します)。
  2. products テーブルと transactions テーブルの両方に user_id があります。これらの ID は異なっていてもかまいませんか? そうでない場合、これはおそらくデータの重複です

クエリを高速化するには:

  1. Identity 列でテーブルをリンクします (つまり、Transactions テーブルには、products テーブルの id 列を参照する product_id int(11) という列が含まれています。これにより、非常に高速な結合が可能になります。
于 2013-07-11T13:11:07.230 に答える
1

このSQLが役立つかどうかはわかりません。試してみませんか?

update transactions as T1   
 inner join ( select T2.id , P.user_id
              from transactions as T2, projects as P
              where T2.product_id = P.link
                and T2.user_id != P.user_id
             ) as T3 on T1.id = T3.id
set T1.user_id = t3.user_id
于 2013-07-11T13:33:23.410 に答える
0

これを試してください。NOT EQUAL の代わりに、LEFT OUTER JOIN でトリックを行うことができます

UPDATE transactions
LEFT OUTER JOIN products ON products.link = transactions.product_id AND 
transactions.user_id = products.user_id
SET transactions.user_id = products.user_id
WHERE products.user_id IS NULL AND transactions.product_id IS NULL
于 2013-07-11T13:10:17.413 に答える
0

2 つのインデックスを作成します。1 つは products.link に、もう 1 つは transactions.product_id に作成します。

また、各インデックスに含まれるフィールドとして user_id を追加することを検討してください (それが mysql でサポートされている場合。私は主に SQL Server プログラミングを行っています)。

于 2013-07-11T13:16:35.493 に答える