teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

5

テーブルweb_list, tel_listのサンプルを追記しました。

2016/09/18 03:04

投稿

cnx
cnx

スコア19

title CHANGED
File without changes
body CHANGED
@@ -28,4 +28,27 @@
28
28
 
29
29
  質問のために一部SQLを変更していましたが、自己検証を繰り返しているうちに端折っているINSERT文+INの組み合わせが非常に時間を掛けていることが分かってきました。この点も踏まえてコメントをいただけるとありがたいです。
30
30
 
31
- master, web_list, tel_listのidを主キーにして速度が上がりました。しかしながら、まだかなり遅い印象で、まだ速くなる余地はないでしょうか。(tell_list, web_list共に2万件で1分ほど掛かります)
31
+ master, web_list, tel_listのidを主キーにして速度が上がりました。しかしながら、まだかなり遅い印象で、まだ速くなる余地はないでしょうか。(tell_list, web_list共に2万件で1分ほど掛かります)
32
+
33
+ **web_list**
34
+ ```web_list
35
+ id|name|inserted
36
+ 11|bob |2016/09/01 12:00
37
+ 12|mary|2016/09/01 13:00
38
+ 15|mary|2016/09/05 10:00
39
+ 16|bob |2016/09/06 15:00
40
+ ```
41
+
42
+ **tel_list**
43
+ ```tel_list
44
+ id|name|inserted
45
+ 13|bob |2016/09/02 17:00
46
+ 14|bob |2016/09/03 15:00
47
+ 17|bob |2016/09/07 15:00
48
+ 18|bob |2016/09/07 18:00
49
+ 19|mary|2016/09/10 10:00
50
+ ```
51
+ 上記のようなイメージです。
52
+ この場合、INのサブクエリーで得られるID一覧は
53
+ 11, 16
54
+ となります。

4

インデックスにより少し高速化されたことの追記

2016/09/18 03:03

投稿

cnx
cnx

スコア19

title CHANGED
File without changes
body CHANGED
@@ -26,4 +26,6 @@
26
26
 
27
27
  nameが同一で、3日以内のレコードが1件以上存在する(0<)ということを条件にしてweb_listからidを列挙してきているのですが……、もっと高速にSQLを書き換えられないものでしょうか。
28
28
 
29
- 質問のために一部SQLを変更していましたが、自己検証を繰り返しているうちに端折っているINSERT文+INの組み合わせが非常に時間を掛けていることが分かってきました。この点も踏まえてコメントをいただけるとありがたいです。
29
+ 質問のために一部SQLを変更していましたが、自己検証を繰り返しているうちに端折っているINSERT文+INの組み合わせが非常に時間を掛けていることが分かってきました。この点も踏まえてコメントをいただけるとありがたいです。
30
+
31
+ master, web_list, tel_listのidを主キーにして速度が上がりました。しかしながら、まだかなり遅い印象で、まだ速くなる余地はないでしょうか。(tell_list, web_list共に2万件で1分ほど掛かります)

3

masterにもインデックスはなかったため修正。update対象が0件でも異様に時間が掛かります

2016/09/17 21:05

投稿

cnx
cnx

スコア19

title CHANGED
File without changes
body CHANGED
@@ -2,7 +2,7 @@
2
2
  web_list, tell_listと名前を付けています。
3
3
  どちらも同じ構造ですが意味合いが異なっています。
4
4
 
5
- masterにはインデックスがありますが、web_list, tel_listにはインデックスはありません。
5
+ master, web_list, tel_listにはインデックスはありません。
6
6
  idは自動採番、insertedは秒単位で全くバラバラです。nameは全体の2割ほどが複数回重複して含まれています。
7
7
 
8
8
  ここで、web_listを上から順番に見ていって、あるレコード(例えばid=n)について【条件1】insertedが後ろ3日(259200秒)以内でかつ【条件2】nameが同一のレコードがあるもののidを抜き出して、masterに付き合わせてflagをアプデートしようとしています。

2

質問のためselect \* masterとしましたが、update master〜でないと遅延の問題が起きないことが分かり修正しました。

2016/09/17 20:43

投稿

cnx
cnx

スコア19

title CHANGED
@@ -1,1 +1,1 @@
1
- 「各レコードから見て後ろ3日以内で条件を満たすレコードが存在するもの」の一覧高速に列挙するSQL
1
+ 「各レコードから見て後ろ3日以内で条件を満たすレコードが存在するもの」の結果一覧から高速にマスターをアップデートするSQL
body CHANGED
@@ -5,10 +5,10 @@
5
5
  masterにはインデックスがありますが、web_list, tel_listにはインデックスはありません。
6
6
  idは自動採番、insertedは秒単位で全くバラバラです。nameは全体の2割ほどが複数回重複して含まれています。
7
7
 
8
- ここで、web_listを上から順番に見ていって、あるレコード(例えばid=n)について【条件1】insertedが後ろ3日(259200秒)以内でかつ【条件2】nameが同一のレコードがあるもののidを抜き出して、masterから情報を**in**を使っ列挙しようとしています。
8
+ ここで、web_listを上から順番に見ていって、あるレコード(例えばid=n)について【条件1】insertedが後ろ3日(259200秒)以内でかつ【条件2】nameが同一のレコードがあるもののidを抜き出して、masterに付き合わせflagをアプデートしようとしています。
9
9
 
10
10
  ```SQL
11
- select * from master where id in (
11
+ update master set flag=1 where id in (
12
12
  select id from web_list as wlst
13
13
  where
14
14
  0 < (select count(id) from tell_list as tlst
@@ -24,4 +24,6 @@
24
24
  と、書いて結果は得られるのですが非常に遅く、ネットなどで検索するとMySQLのin+サブクエリーは遅いのでjoinに書き換えた方が良いといった意見なども見受けられました。
25
25
  AWSのRDS(large)などでテストしても各テーブルが数千件を超えるとまともに結果が返却されない(数十分かかってタイムアウト)といった状態です。
26
26
 
27
- nameが同一で、3日以内のレコードが1件以上存在する(0<)ということを条件にしてweb_listからidを列挙してきているのですが……、もっと高速にSQLを書き換えられないものでしょうか。
27
+ nameが同一で、3日以内のレコードが1件以上存在する(0<)ということを条件にしてweb_listからidを列挙してきているのですが……、もっと高速にSQLを書き換えられないものでしょうか。
28
+
29
+ 質問のために一部SQLを変更していましたが、自己検証を繰り返しているうちに端折っているINSERT文+INの組み合わせが非常に時間を掛けていることが分かってきました。この点も踏まえてコメントをいただけるとありがたいです。

1

分かりやすくしようと前後3日かつbetweenを使う形にしましたが、自分を含んでしまうため実際に試したSQLと条件に則した条件とSQLに戻しました

2016/09/17 20:41

投稿

cnx
cnx

スコア19

title CHANGED
@@ -1,1 +1,1 @@
1
- 「各レコードから見て後3日以内で条件を満たすレコードが存在するもの」の一覧を高速に列挙するSQL
1
+ 「各レコードから見て後3日以内で条件を満たすレコードが存在するもの」の一覧を高速に列挙するSQL
body CHANGED
@@ -5,7 +5,7 @@
5
5
  masterにはインデックスがありますが、web_list, tel_listにはインデックスはありません。
6
6
  idは自動採番、insertedは秒単位で全くバラバラです。nameは全体の2割ほどが複数回重複して含まれています。
7
7
 
8
- ここで、web_listを上から順番に見ていって、あるレコード(例えばid=n)について【条件1】insertedが後3日(259200秒)以内でかつ【条件2】nameが同一のレコードがあるもののidを抜き出して、masterから情報を**in**を使って列挙しようとしています。
8
+ ここで、web_listを上から順番に見ていって、あるレコード(例えばid=n)について【条件1】insertedが後3日(259200秒)以内でかつ【条件2】nameが同一のレコードがあるもののidを抜き出して、masterから情報を**in**を使って列挙しようとしています。
9
9
 
10
10
  ```SQL
11
11
  select * from master where id in (
@@ -14,9 +14,10 @@
14
14
  0 < (select count(id) from tell_list as tlst
15
15
  where
16
16
  wlst.name = tlst.name
17
- and
17
+ and
18
+ wlst.inserted < tlst.inserted
19
+ and
18
- tlst.inserted between wlst.inserted - 259200
20
+ tlst.inserted < wlst.inserted + 259200)
19
- and wlst.inserted + 259200)
20
21
  )
21
22
  );
22
23
  ```