大学のコースに関する情報を含むデータベースを構築しています。各コースを関連付けることができます
- 一人または複数の著者
- 1 つまたは複数の分野
- 1つまたは複数の機関
- 1 つまたは複数のレベル
私のデータベースには次のテーブルが含まれています。
- コース (cou_id, cou_name, cou_number, cou_year, cou_term)
- 著者 (aut_id、aut_last)
- 規律 (dis_id、dis_name)
- 機関 (ins_id、ins_name、ins_classification)
- レベル (lev_id、lev_name)
- authorcourse (リンク テーブル)
- コース規律(リンクテーブル)
- コース機関(リンクテーブル)
- courselevel (リンク テーブル)
データベースからすべてのコース (および対応する著者、分野、教育機関、およびレベル情報) を取得するために、次のクエリを使用します。
SELECT DISTINCT aut_last, c.cou_id, cou_name, cou_number, cou_year, cou_term, dis_name, ins_name, ins_classification, lev_name
FROM authorcourse ac1
INNER JOIN authorcourse ac2
ON ac1.cou_id = ac2.cou_id
INNER JOIN author a
ON ac2.aut_id=a.aut_id
INNER JOIN course c
ON ac2.cou_id = c.cou_id
INNER JOIN coursediscipline cd1
ON ac2.cou_id = cd1.cou_id
INNER JOIN coursediscipline cd2
ON cd1.cou_id = cd2.cou_id
INNER JOIN discipline d
ON cd2.dis_id = d.dis_id
INNER JOIN courseinstitution ci1
ON ac2.cou_id = ci1.cou_id
INNER JOIN courseinstitution ci2
ON ci1.cou_id = ci2.cou_id
INNER JOIN institution i
ON ci2.ins_id = i.ins_id
INNER JOIN courselevel cl1
ON ac2.cou_id = cl1.cou_id
INNER JOIN courselevel cl2
ON cl1.cou_id = cl2.cou_id
INNER JOIN level l
ON cl2.lev_id = l.lev_id
このクエリは、データベースに「単純な」関係を持つ 15 のコースがある場合にうまく機能します。例えば:
cou_name = 'course1', cou_number = 'C1', cou_year = '1999', cou_term = 'summer'
aut_last = 'Doe1'
dis_name = 'discipline1'
ins_name = 'institution1', ins_classification = 'classification1'
lev_name = 'level1'
--> 行 0 ~ 14 を表示 (合計 15、クエリにかかった時間は 0.0118 秒) EXPLAIN は次の表を生成します。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ac1 index cou_id aut_id 2 NULL 15 Using index; Using temporary
1 SIMPLE ac2 ref PRIMARY,aut_id,cou_id cou_id 2 ccdb.ac1.cou_id 1 Using index
1 SIMPLE a eq_ref PRIMARY PRIMARY 2 ccdb.ac2.aut_id 1
1 SIMPLE c eq_ref PRIMARY PRIMARY 2 ccdb.ac2.cou_id 1 Using where
1 SIMPLE cd1 ref PRIMARY,cou_id PRIMARY 2 ccdb.ac1.cou_id 1 Using index
1 SIMPLE cd2 ref PRIMARY,cou_id,dis_id PRIMARY 2 ccdb.ac2.cou_id 1 Using where; Using index
1 SIMPLE d eq_ref PRIMARY PRIMARY 2 ccdb.cd2.dis_id 1
1 SIMPLE ci1 ref PRIMARY,cou_id PRIMARY 2 ccdb.ac2.cou_id 1 Using where; Using index
1 SIMPLE ci2 ref PRIMARY,cou_id,ins_id PRIMARY 2 ccdb.ac2.cou_id 1 Using where; Using index
1 SIMPLE i eq_ref PRIMARY PRIMARY 2 ccdb.ci2.ins_id 1
1 SIMPLE cl1 ref PRIMARY,cou_id PRIMARY 2 ccdb.cd1.cou_id 1 Using where; Using index
1 SIMPLE cl2 ref PRIMARY,cou_id,lev_id PRIMARY 2 ccdb.cl1.cou_id 1 Using where; Using index
1 SIMPLE l eq_ref PRIMARY PRIMARY 2 ccdb.cl2.lev_id 1
問題:複数の関係を持つ 15 のコースがある場合、パフォーマンスが劇的に低下します。コース例:
cou_name = 'course1', cou_number = 'C1', cou_year = '1999', cou_term = 'summer'
aut_last = 'Doe1', 'Doe', 'Doe3', 'Doe4'
dis_name = 'discipline1', 'discipline2', 'discipline3', 'discipline4'
ins_name = 'institution1'(ins_classification = 'classification1'), 'institution2'(ins_classification = 'classification2'), 'institution3'(ins_classification = 'classification3'), 'institution4' (ins_classification = 'classification4')
lev_name = 'level1', 'level2', 'level3', 'level4'
--> 行 0 ~ 29 を表示 (合計 3,840、クエリに 14.7039 秒かかりました) EXPLAIN は次の表を生成します。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c ALL PRIMARY NULL NULL NULL 15 Using temporary
1 SIMPLE ac1 ref PRIMARY,aut_id,cou_id cou_id 2 ccdb.c.cou_id 2 Using index
1 SIMPLE a eq_ref PRIMARY PRIMARY 2 ccdb.ac1.aut_id 1
1 SIMPLE ac2 ref cou_id cou_id 2 ccdb.c.cou_id 2 Using index
1 SIMPLE cd1 ref PRIMARY,cou_id cou_id 2 ccdb.ac1.cou_id 2 Using where; Using index
1 SIMPLE cd2 ref PRIMARY,cou_id,dis_id cou_id 2 ccdb.c.cou_id 2 Using index
1 SIMPLE d eq_ref PRIMARY PRIMARY 2 ccdb.cd2.dis_id 1
1 SIMPLE ci1 ref PRIMARY,cou_id cou_id 2 ccdb.ac1.cou_id 2 Using where; Using index
1 SIMPLE ci2 ref PRIMARY,cou_id,ins_id cou_id 2 ccdb.ac2.cou_id 2 Using where; Using index
1 SIMPLE i eq_ref PRIMARY PRIMARY 2 ccdb.ci2.ins_id 1
1 SIMPLE cl1 ref PRIMARY,cou_id cou_id 2 ccdb.c.cou_id 2 Using index
1 SIMPLE cl2 ref PRIMARY,cou_id,lev_id cou_id 2 ccdb.ci2.cou_id 2 Using where; Using index
1 SIMPLE l eq_ref PRIMARY PRIMARY 2 ccdb.cl2.lev_id 1
PHP Web サイトを実行すると、「致命的なエラー: 最大実行時間が 30 秒を超えました...」というエラーが表示されます。</p>
質問: このクエリを高速化するにはどうすればよいですか? 結合のいくつかの異なる組み合わせを試し、(EXPLAIN の結果でわかるように) 関連する可能性があると思われるすべての列にインデックスを付けました。
どんな助けでも大歓迎です。