LEFT JOINとサブクエリを組み合わせたクエリがあります。データセットは非常に大きく、ステートメントの実行時間は70秒以上です。
SELECT
s.siblings,
l.id
FROM
`list` l
INNER JOIN
child c ON c.id = l.child_id
INNER JOIN
parent p ON p.id = c.parent_id
LEFT JOIN (
SELECT COUNT(c.id) AS siblings, c.id, c.parent_id
FROM child c
GROUP BY c.id
) AS s ON s.parent_id = c.parent_id AND s.id != c.id
WHERE
l.country = 1
GROUP BY l.id, s.siblings
ORDER BY l.dateadded
このクエリは、国のすべてのリストを返す必要があります。各リストは、固有の赤ちゃんに固有のものです。リストごとに、同じ親を持つ子の数を返したいと思います。
LEFT JOINサブクエリを削除すると、フェッチ時間は0.1秒になります。クエリをより効率的にする方法はありますか?
クエリが遅い主な理由は、サブクエリの結合です。これはインデックスを使用しません。次に、派生テーブル(サブクエリ)と結合するだけでなく、サブクエリ列に基づいて合計結果をグループ化します-GROUP BY l.id, s.Siblings
この場合、次のことが役立ちます。
これはバリアントを持つ可能性がありますが、多くの場合、結合を使用した複雑なサブクエリのセットよりも高速で、サーバーの負荷が低くなります。
クエリには多くの不必要な複雑な機能があります。さらに、派生テーブルの_GROUP BY c.id
_(child (id)
がそのテーブルの主キーであると想定)は完全に冗長に見えます。クエリの結果は、siblings
列では常に_1
_である必要があります。これは、おそらく望ましい結果ではありません。
これはあなたが望むことをする(兄弟の数を見つける)はるかに簡単な方法で:
_SELECT
s.cnt - 1 AS siblings,
l.id
FROM
`list` AS l
INNER JOIN
child AS c ON c.id = l.child_id
INNER JOIN
( SELECT c.parent_id, COUNT(*) AS cnt
FROM child AS c
GROUP BY c.parent_id
) AS s ON s.parent_id = c.parent_id
WHERE
l.country = 1
ORDER BY l.dateadded ;
_