1

私は MYSQL を学習している最中で、疑問に思っていることがあります。

この単純なシナリオを考えてみましょう: オンライン コースを受講するための架空の Web サイトで、次の 4 つのテーブルで構成されています: 学生、教師、コース、および登録 (学生が登録したコースごとに 1 つのエントリ)

DB 生成コードは github にあります。

提供された DB はわかりやすくするために小さいものですが、私が助けを必要としていることに関連するようにするために、効率が実際の問題となる十分な大きさのデータベースを使用していると仮定しましょう。



私が MYSQL で理解している限り、'Charles Darwin' によって教えられている学生のテーブルが必要な場合、1 つの可能なクエリは次のようになります。

方法 1

SELECT Students.name FROM Teachers
INNER JOIN Courses ON Teachers.id = Courses.teacher_id
INNER JOIN Registrations ON Courses.id = Registrations.course_id
INNER JOIN Students ON Registrations.student_id = Students.id
WHERE Teachers.name = "Charles Darwin"

これは確かに私たちが望むものを返します。

+----------------+
| name           |
+----------------+
| John Doe       |
| Jamie Heineman |
| Claire Doe     |
+----------------+


だからここに私の質問があります:

私の (非常に) 限られた MYSQL の知識では、ここではJOIN要素を Teachers テーブルに -ingしているように思えます。クエリの。

私の「直感」によると、最初に必要な教師の単一の行を取得し、代わりに残りのものをそれに結合する方がはるかに効率的です。

方法 2

SELECT Students.name FROM (SELECT Teachers.id FROM Teachers WHERE Teachers.name = 
"Charles Darwin") as Teacher
INNER JOIN Courses ON Teacher.id = Courses.teacher_id
INNER JOIN Registrations ON Courses.id = Registrations.course_id
INNER JOIN Students ON Registrations.student_id = Students.id

しかし、それは本当にそうですか?何千人もの教師と生徒がいると仮定すると、これは最初のクエリよりも効率的ですか? MYSQL は、メソッド 1 のクエリをより効率的に実行できるように解析できるほどスマートである可能性があります。


また、誰かがさらに効率的なクエリを提案できる場合は、私もそれを聞くことに非常に興味があります.

注: クエリの効率性を把握するために使用する方法を以前に読んだことEXPLAINがありますが、結果を解読できるほど十分に MYSQL を理解していません。ここでの洞察も大歓迎です。

4

1 に答える 1

1

私の「直感」によると、最初に必要な教師の単一の行を取得し、代わりに残りのものをそれに結合する方がはるかに効率的です。

predicate を使用して、メソッド 1 で teacher の単一の行を取得していTeachers.name = "Charles Darwin"ます。Teacherクエリ オプティマイザーは、他のテーブルを結合する前に、この述語を使用してセットを制限する方が効率的であると判断する必要があります。

オプティマイザーを信頼しない場合、またはオプティマイザーの作業を減らしたい場合は、クエリで指定した順序で MySQL がテーブルを読み取るようにする代わりに、SELECT STRAIGHT_JOIN ...orを使用して、テーブルの読み取り順序を強制することもできます。STRAIGHT_JOININNER_JOIN

2 番目のクエリの結果は同じですが、教師のサブクエリ用に一時テーブルが作成されるため、効率が低下する可能性があります。

EXPLAINドキュメントEXPLAINは、出力の解釈方法に関する優れた情報源です。

于 2013-07-25T23:29:14.640 に答える