0

これは19時間にわたる悪夢でした。

本質的に、いくつかのテーブル間で大きなデータセットを結合する必要がある非常に大きなクエリがあります。結合を行った後、元のテーブルを select ステートメントのデータで更新する必要があります。SELECT ステートメントは非常に高速ですが、UPDATE ステートメントは非常に低速です。

これが select ステートメントです。

SELECT l.col1,
       l.col2,
       l.col3,
       p.personid
FROM table1 p
LEFT JOIN table2 l ON (l.col1 = p.col1)
LEFT JOIN
  (SELECT name,
          col AS 'col2'
   FROM tbl3 f
   WHERE f.col LIKE '%-F') pcf ON (pcf.col1 = p.col1)
LEFT JOIN
  (SELECT name,
          col AS 'col3'
   FROM tbl4 f
   WHERE f.col LIKE '%-M') pcm ON (pcm.col1 = p.col1)
WHERE p.requestid = '1928'

ここで、EXACT SAME の一連の JOIN を取得して UPDATE コンテキスト内に配置すると、クエリに時間がかかります。

UPDATE table1 p
LEFT JOIN table2 l ON (l.col1 = p.col1)
LEFT JOIN
  (SELECT name,
          col AS 'col2'
   FROM tbl3 f
   WHERE f.col LIKE '%-F') pcf ON (pcf.col1 = p.col1)
LEFT JOIN
  (SELECT name,
          col AS 'col3'
   FROM tbl4 f
   WHERE f.col LIKE '%-M') pcm ON (pcm.col1 = p.col1)
SET p.col1 = l.col1,
    p.col2 = l.col2,
    p.col3 = l.col3
WHERE p.requestid = '1928'

では、なぜ UPDATE JOIN ステートメントは SELECT JOIN ステートメントよりもはるかに時間がかかるのでしょうか? ずいぶん長い時間。そして、私はすでに一時テーブルを試しましたが、うまくいきませんでした。

参考までに、50k レコード以上のテーブルを扱っています。

EXPLAIN の結果が気になる方は、select クエリを EXPLAIN するとこうなります (更新に Explain を使用できないようですが)。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY p   ALL NULL    NULL    NULL    NULL    613246  Using where
1   PRIMARY l   eq_ref  PRIMARY,name_3,name,name_2  PRIMARY 257 drilldev_db.p.lastname  1   
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    23435   
1   PRIMARY <derived3>  ALL NULL    NULL    NULL    NULL    13610   
1   PRIMARY <derived4>  ALL NULL    NULL    NULL    NULL    13053   
1   PRIMARY <derived5>  ALL NULL    NULL    NULL    NULL    8273    
1   PRIMARY <derived6>  ALL NULL    NULL    NULL    NULL    11481   
1   PRIMARY <derived7>  ALL NULL    NULL    NULL    NULL    6708    
1   PRIMARY <derived8>  ALL NULL    NULL    NULL    NULL    9588    
1   PRIMARY <derived9>  ALL NULL    NULL    NULL    NULL    5494    
1   PRIMARY <derived10> ALL NULL    NULL    NULL    NULL    6981    
1   PRIMARY <derived11> ALL NULL    NULL    NULL    NULL    4107    
1   PRIMARY <derived12> ALL NULL    NULL    NULL    NULL    5973    
1   PRIMARY <derived13> ALL NULL    NULL    NULL    NULL    3851    
1   PRIMARY <derived14> ALL NULL    NULL    NULL    NULL    4935    
1   PRIMARY <derived15> ALL NULL    NULL    NULL    NULL    3574    
1   PRIMARY <derived16> ALL NULL    NULL    NULL    NULL    5793    
1   PRIMARY <derived17> ALL NULL    NULL    NULL    NULL    4706    
17  DERIVED f   ref year,gender gender  257     364263  Using where; Using temporary; Using filesort
16  DERIVED f   ref year,gender gender  257     397322  Using where; Using temporary; Using filesort
15  DERIVED f   range   year,gender year    4   NULL    54092   Using where; Using temporary; Using filesort
14  DERIVED f   range   year,gender year    4   NULL    54092   Using where; Using temporary; Using filesort
13  DERIVED f   range   year,gender year    4   NULL    62494   Using where; Using temporary; Using filesort
12  DERIVED f   range   year,gender year    4   NULL    62494   Using where; Using temporary; Using filesort
11  DERIVED f   range   year,gender year    4   NULL    69317   Using where; Using temporary; Using filesort
10  DERIVED f   range   year,gender year    4   NULL    69317   Using where; Using temporary; Using filesort
9   DERIVED f   ref year,gender gender  257     364263  Using where; Using temporary; Using filesort
8   DERIVED f   range   year,gender year    4   NULL    94949   Using where; Using temporary; Using filesort
7   DERIVED f   ref year,gender gender  257     364263  Using where; Using temporary; Using filesort
6   DERIVED f   ref year,gender gender  257     397322  Using where; Using temporary; Using filesort
5   DERIVED f   ref year,gender gender  257     364263  Using where; Using temporary; Using filesort
4   DERIVED f   ref year,gender gender  257     397322  Using where; Using temporary; Using filesort
3   DERIVED f   ALL NULL    NULL    NULL    NULL    37045   Using where
2   DERIVED f   ALL NULL    NULL    NULL    NULL    37045   Using where

ありがとう!

-b

4

2 に答える 2

0

これについて少し考えてみましょう。テーブルの行を選択する場合 (それらを取得するだけ) と、すべての行を更新する場合、それぞれの行を順に更新する場合、どれに時間がかかりますか? n 行を読み取るか、n 行を変更 (更新) しますか?

本の 10 行を読むのと同じ 10 行を紙に書くのと比較してください。どちらが時間がかかりますか?

また、読んでいる行と更新している行が多いほど、違いが大きくなります。本の行を読むことと書くことの違いが大きくなるのと同じように、より多くの行を読んだり書いたりしていました。

于 2013-08-29T18:30:20.773 に答える