2

2つのMySQLクエリについて考えてみます。

SELECT ue.userid,e.courseid 
FROM (SELECT id,courseid FROM mdl_enrol WHERE status = 0 AND courseid IN (46)) e 
INNER JOIN (SELECT enrolid,userid FROM mdl_user_enrolments ) ue ON ue.enrolid = e.id 
INNER JOIN (SELECT userid FROM mdl_userdata) ud ON ue.userid = ud.userid

-

SELECT ue.userid,e.courseid 
FROM mdl_enrol e 
INNER JOIN mdl_user_enrolments ue ON ue.enrolid = e.id 
INNER JOIN mdl_userdata ud ON ue.userid = ud.userid
WHERE e.status = 0 AND e.courseid IN (46)

下のクエリは上のクエリよりもはるかに高速ですが、なぜですか?パフォーマンスを向上させるには、必要な列のみを選択する必要があることを読みました。また、各JOINで結合するデータの量が減るので、トップクエリのパフォーマンスが向上するはずです。明らかに、データベースがどのように機能するかについての私の理解は間違っていますが、誰かがこれを片付けることができれば、それは大いにありがたいです。EXPLAINは、一番下のクエリがはるかに高速であることも確認します。

どうもありがとう。

4

1 に答える 1

4

最初のクエリで、mysqlはmdl_enrolテーブルからサブセットを選択し、メモリに入力する必要があります。 したがって、メモリ内の大量のデータを選択します。それを行った後、データを結合します。データが結合されてクライアントに返送されるまで、すべてのデータを配置するのに十分なメモリがない場合は、ハードドライブに一時テーブルが作成されます。ほとんどの場合、mysqlオプティマイザは、間違いを修正して実行プランを改善しようとするほどクールではありません。それが遅い理由です。mdl_user_enrolmentsmdl_userdata

一方、2番目のクエリでは、mysqlは正確に何を選択する必要があるかを認識しており、必要なデータの少量のみを選択します。このシナリオでは、インデックスを使用できます(必要なすべてのインデックスが作成されていることを前提としています)。だからそれは速いです。

于 2012-09-11T08:46:07.270 に答える