2

現在、2つのテーブルからメトリックデータを選択するクエリがありますが、プロジェクトは他の2つのテーブルからクエリを実行します(1つは所有プロジェクト、もう1つはユーザーがアクセスできるプロジェクトです)。

SELECT v.`projectID`,
(SELECT COUNT(m.`session`) 
    FROM `metricData` m
    WHERE m.`projectID` = v.`projectID`) AS `sessions`,
(SELECT COUNT(pb.`interact`)
    FROM `interactionData` pb WHERE pb.`projectID` = v.`projectID` GROUP BY pb.`projectID`) AS `interactions`
FROM `medias` v
LEFT JOIN `projectsExt` pa ON v.`projectsExtID` = pa.`projectsExtID`
WHERE (pa.`user` = '1' OR v.`ownerUser` = '1')
GROUP BY v.`projectID`

時間がかかりすぎて1〜2秒かかります。これは明らかにマルチ左結合シナリオです。しかし、私は速度を向上させるためのいくつかのアイデアを持っており、その考えは原則として何であるか疑問に思いました。私は:-

  • 結合を行うのではなく、クエリでリストを選択してからデータを取得してみてください。これがどのように機能するかわからない。
  • 別のクエリでselectを実行してprojectIDを取得し、その後、各projectIDに対してクエリを実行します。これにより、数百、場合によっては数千のリクエストが発生する可能性がありますが、処理には適している可能性がありますか?
  • 他のアイデア?
4

2 に答える 2

4

ここには2つの質問があります。

  1. 2秒以内に結果を得るにはどうすればよいですか
  2. どうすれば左結合を回避できますか。

#1に正しく答えるには、より多くの情報が必要です。この特定のクエリの説明計画などの技術情報は、良いスタートです。アクセスするすべてのテーブルのSHOWCREATETABLEと、それらに含まれる行の数があればさらに良いでしょう。

しかし、もっと機能的な情報もありがたいです。あなたが答えようとしている質問は正確には何ですか?現在、2つの異なるメディアセットを見ているようです。

  1. projectsExtに一致する行がない場合、medias.ownerUserは「1」と等しくなければなりません(「1」は文字列btwであると想定されていますか?)
  2. または、projectsExt.userが「1」に等しくなければならないprojectsExtに数学行が1つだけあります(「1」は文字列btwであると想定されていますか?)

#1に答えるのに十分な情報が不足しているため、#2-「左結合を回避する方法」に答えることができます。答えは次のとおりです。1つは一致するものと一致しないものの2つのセットのUNIONを記述します。

SELECT v.`projectID`
,      (
       SELECT COUNT(m.`session`) 
       FROM `metricData` m
       WHERE m.`projectID` = v.`projectID`
       ) AS `sessions`
,      (
       SELECT COUNT(pb.`interact`)
       FROM `interactionData` pb
       WHERE pb.`projectID` = v.`projectID`
       GROUP BY pb.`projectID`
) AS `interactions`
FROM ( 
    SELECT      v.projectID
    FROM medias 
    WHERE ownerUser = '1'
    GROUP BY projectID
    UNION ALL
    SELECT      v.projectID
    FROM medias v
    INNER JOIN projectsExt pa
    ON         v.projectsExtID = pa.projectsExtID
    WHERE      v.ownerUser != '1'
    AND        pa.user = '1'
    GROUP BY v.`projectID
) v
于 2012-04-05T14:31:42.287 に答える
0

代わりに、すべてを左結合にリファクタリングしようとしましたか?常に同じフィールドでグループ化する方法を考えると、問題にはならないはずです。EXPLAINそれを試して、ボトルネックが何であるかを確認するために投稿してください。

エンジンは結合をはるかに高度に最適化できるため、副選択は結合よりもパフォーマンスが低くなります。実際、副選択は通常、該当する場合、可能な場合はエンジンによって結合に書き換えられます。

経験則として、クエリを分割してもメリットはありません。得られるのはオーバーヘッドとオプティマイザの混乱だけです。いつものように、このルールには例外がありますが、伝統的にできることを実行し、そのようなアプローチに熱心であることを知った後に、それらは機能します。

于 2012-04-05T14:00:43.973 に答える