困りごと
下表のようにbaseball.pitchテーブルにbaseball.playerの情報をjoinしようと思っています。joinにあたっては、投手などのIDだけでは一意には決まらず、年度とIDとの組み合わせでjoinの組み合わせ相手が一意に決まる形式になっています。
以下のようにjoin区を二つつなげて実行したのですが、実行に10分程度かかってしまいます。一方joinを1つだけにした場合、1,2秒で終了します。
解決したいこと
本例のように、joinを複数実施する時に遅くしないようにどうしたらいいでしょうか?
また、Primary Key設定はしていません(こういった場合に設定したら早くなるのかがわからないため)。
テーブル概要
baseball.pitch (70万レコード)
年度 | 投手ID | 打者ID | 投げた球の種類 | 時刻 | アウトカウント |
---|---|---|---|---|---|
2017 | 100 | 102 | ストレート | 19:00 | 0 |
2017 | 100 | 102 | ストレート | 19:01 | 0 |
2017 | 100 | 102 | スライダー | 19:01 | 0 |
2017 | 101 | 100 | カーブ | 19:03 | 1 |
、、、 | 、、、 | 、、、 | 、、、 | 、、、 | |
2018 | 100 | 102 | カーブ | 20:00 | 0 |
2018 | 100 | 102 | カーブ | 20:00 | 0 |
2018 | 100 | 102 | カーブ | 20:02 | 0 |
、、、 | 、、、 | 、、、 | 、、、 | 、、、 | 、、、 |
baseball.player (3000レコード)
年度 | 選手ID | 身長 | 年俸 | 氏名 | 生年月日 |
---|---|---|---|---|---|
2017 | 100 | 180 | 20000 | A | 1990/1/1 |
2017 | 101 | 175 | 10000 | B | 1989/3/1 |
2017 | 102 | 170 | 8000 | C | 1991/5/1 |
2018 | 100 | 180 | 15000 | A | 1982/1/1 |
、、、 | 、、、 | 、、、 | 、、、 | 、、、 | 、、、 |
クエリー1(baseball.pitchに集約)
MySQL
1explain select p.年度, 投手テーブル.年俸 as 投手年俸, 身長 as 打者身長 2from baseball.pitch as p 3 join (select 年度, 年俸, 選手ID from baseball.player) as 投手テーブル 4 on p.年度 = 投手テーブル.年度 5 and p.投手ID = 投手テーブル.選手ID 6 join (select 年度, 選手ID, 身長, 年俸 from baseball.player) as 打者テーブル 7 on p.年度 = 打者テーブル.年度 8 and p.打者ID = 打者テーブル.選手ID 9limit 10000;
Explainで実行計画結果(クエリー1)。
Indexを貼らない場合
mySQL
1+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 2| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 3+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 4| 1 | SIMPLE | player | NULL | ALL | NULL | NULL | NULL | NULL | 2704 | 100.00 | NULL | 5| 1 | SIMPLE | player | NULL | ALL | NULL | NULL | NULL | NULL | 2704 | 10.00 | Using where; Using join buffer (Block Nested Loop) | 6| 1 | SIMPLE | p | NULL | ALL | NULL | NULL | NULL | NULL | 771848 | 0.10 | Using where; Using join buffer (Block Nested Loop) | 7+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 83 rows in set, 1 warning (0.00 sec)
Indexを貼った場合
mySQL
1+----+-------------+--------+------------+------+---------------+---------------+---------+---------------------------------------+--------+----------+-------------+ 2| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 3+----+-------------+--------+------------+------+---------------+---------------+---------+---------------------------------------+--------+----------+-------------+ 4| 1 | SIMPLE | p | NULL | ALL | id_year_index | NULL | NULL | NULL | 771848 | 100.00 | Using where | 5| 1 | SIMPLE | player | NULL | ref | id_year_index | id_year_index | 10 | baseball.p.年度,baseball.p.投手ID | 1 | 100.00 | NULL | 6| 1 | SIMPLE | player | NULL | ref | id_year_index | id_year_index | 10 | baseball.p.年度,baseball.p.打者ID | 1 | 100.00 | NULL | 7+----+-------------+--------+------------+------+---------------+---------------+---------+---------------------------------------+--------+----------+-------------+ 83 rows in set, 1 warning (0.00 sec)
Warning内容
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Note | 1003 | /* select#1 */ select `baseball`.`p`.`年度` AS `年度`,`baseball`.`player`.`年俸` AS `投手年俸`,`baseball`.`player`.`身長` AS `打者身長` from `baseball`.`pitch` `p` join `baseball`.aseball`.`player` where ((`baseball`.`player`.`選手ID` = `baseball`.`p`.`投手ID`) and (`baseball`.`player`.`選手ID` = `baseball`.`p`.`打者ID`) and (`baseball`.`player`.`年度` = `baseball`.`p`.`年度eball`.`player`.`年度` = `baseball`.`p`.`年度`)) limit 10000 | +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
クエリー2(baseball.playerに集約)
MySQL
1explain select * from baseball.player as 選手 2 left join baseball.pitch as 投手 3 on 選手.年度 = 投手.年度 4 and 選手.選手ID = 投手.投手ID 5 left join baseball.pitch as 打者 6 on 選手.年度 = 打者.年度 7 and 選手.選手ID = 打者.打者ID;
Explainで実行計画結果(クエリー2)。
Indexを貼った場合
mySQL
1+----+-------------+--------+------------+------+-----------------------------------+---------------------+---------+-------------------------------------------------+------+----------+-------+ 2| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 3+----+-------------+--------+------------+------+-----------------------------------+---------------------+---------+-------------------------------------------------+------+----------+-------+ 4| 1 | SIMPLE | 選手 | NULL | ALL | NULL | NULL | NULL | NULL | 2704 | 100.00 | NULL | 5| 1 | SIMPLE | 投手 | NULL | ref | id_year_index,id_year_index_toshu | id_year_index_toshu | 10 | baseball.選手.年度,baseball.選手.選手ID | 1002 | 100.00 | NULL | 6| 1 | SIMPLE | 打者 | NULL | ref | id_year_index,id_year_index_toshu | id_year_index | 10 | baseball.選手.年度,baseball.選手.選手ID | 734 | 100.00 | NULL | 7+----+-------------+--------+------------+------+-----------------------------------+---------------------+---------+-------------------------------------------------+------+----------+-------+ 83 rows in set, 1 warning (0.00 sec)
Indexを貼らない場合
mySQL
1+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 2| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 3+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 4| 1 | SIMPLE | 選手 | NULL | ALL | NULL | NULL | NULL | NULL | 2704 | 100.00 | NULL | 5| 1 | SIMPLE | 投手 | NULL | ALL | NULL | NULL | NULL | NULL | 771848 | 100.00 | Using where; Using join buffer (Block Nested Loop) | 6| 1 | SIMPLE | 打者 | NULL | ALL | NULL | NULL | NULL | NULL | 771848 | 100.00 | Using where; Using join buffer (Block Nested Loop) | 7+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ 83 rows in set, 1 warning (0.00 sec) 9
回答2件
あなたの回答
tips
プレビュー