sql >> データベース >  >> RDS >> Mysql

mysqlクエリの最適化(好き/嫌い)

    パフォーマンスの面では、これらの相関するサブクエリはあなたの昼食を食べることができます。また、MySQLがそれらを処理する方法のために、大規模なセットの場合はランチボックスもむさぼり食います。これらのサブクエリはそれぞれ、外部クエリで返されるすべての行に対して実行されます。そして、それは大きなセットでは非常に高価になる可能性があります。

    別のアプローチは、インラインビューを使用してすべてのコンテンツの好き嫌いを具体化し、それに結合操作を実行することです。

    ただし、このアプローチもコストがかかる可能性があります。特に、数十億行のうち、数行のコンテンツ行に対してのみ投票「カウント」が必要な場合はそうです。多くの場合、調べて返す必要のある行の数を制限するために、インラインビューに組み込むこともできる外部クエリからの述語があります。

    そのインラインビューへのOUTER結合を使用したいので、クエリと同等の結果が返されます。 contentから行を返す voteに一致する行がない場合 テーブル。

    SELECT [... BUNCH OF FIELDS ...]
         , COALESCE(v.likes,0) AS likes
         , COALESCE(v.dislikes,0) AS dislikes
         , COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
      FROM content c
      LEFT
      JOIN ( SELECT vt.cId
                  , SUM(vt.vote = '.Constants::LIKE.') AS likes
                  , SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
                  , MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
               FROM votes vt
              GROUP
                 BY vt.cId
           ) v
        ON v.cId = c.contentId
    
           [... OTHER STUFF ... ]
    

    インラインビュークエリ(別名v)に注意してください )voteのすべての単一行を確認します テーブル。サブセットのみが必要な場合は、適切な述語を追加することを検討してください(WHERE句で、または別のテーブルへのJOINとして)。 [... OTHER STUFF ...]からの表示はありません クエリで、contentからほんの数行を返すかどうか または、likesで並べ替えているために、すべての行が必要な場合 、など。

    contentから選択された少数の行の場合 テーブルでは、(クエリのように)相関サブクエリを使用すると、実際には、巨大なインラインビューを実体化して、それに対して結合操作を実行するよりも高速になります。

    ああ...そして両方のクエリについて、voteの適切なインデックスは言うまでもありません cIdの先頭の列を持つテーブル パフォーマンスにメリットがあります。インラインビューの場合、MySQLのオーバーヘッドでfilesortを実行する必要はありません。 GROUP BYを実行するために、これらすべての行を操作します。また、相関サブクエリの場合は、フルスキャンではなくインデックス範囲スキャンを使用する必要があります。



    1. 一時テーブルのサイズを制限するにはどうすればよいですか?

    2. postgresqlの時制DBでの本能的な値の抽出と平均化

    3. phpmysqlの二重の日付範囲

    4. PostgreSQL特権付与が表示されない