2017-10-03 20 views
0

最適化COUNT(DISTINCT)SQLクエリ

Aは、2つの列を含み、B(数千)と比較して行の比較的少量を有する:

id, build_id (string) 

Bが含まれてい

id, build_id (string), task_id (string) 

特定のビルドには多くのタスクが存在する可能性があります。私はすべてのビルドと各ビルドの最新のタスクIDとそのビルドのタスク数を含むテーブルを取得したいと思います。私が持っている質問は以下の通りです:

SELECT 
    A.build_id, 
    MAX(B.id) as latest_task_id, 
    COUNT(DISTINCT B.task_id) AS task_count 
FROM 
    A 
LEFT OUTER JOIN 
    B ON B.build_id = A.build_id 
GROUP BY 
    A.build_id 

これを最適化する方法はありますか? build_idとtask_idにはすでに索引があります。

UPDATE:これはpostgresの上にある9.6+

+0

どのpostgresバージョンですか?これはあなたが9.6+で最適化できるように重要です –

+0

MySQLとpostgresqlはSQL実装が異なる2つの異なる製品です。あなたはどちらを使いますか?また、なぜクエリを最適化する必要がありますか?それは遅いですか?はいの場合、それはどれくらい遅いですか?影響を受けるレコードの数はどれくらいですか? – Shadow

+1

実際に使用しているデータベースで質問にタグを付けてください。互換性のないデータベースタグを削除しました。 –

答えて

0

join前に集計してみてください。

SELECT A.build_id, 
     MAX(B.id) as latest_task_id, 
     COUNT(B.task_id) AS task_count 
FROM A LEFT OUTER JOIN 
    (SELECT B.build_id, B.task_id, MAX(B.id) as id 
     FROM B 
     GROUP BY B.build_id, B.task_id 
    ) B 
    ON B.build_id = A.build_id 
GROUP BY A.build_id; 

時々、全体の集約のためのアルゴリズムはCOUNT(DISTINCT)のためのより効率的です。

このクエリでは、B(build_id, task_id, id)のインデックスを試すこともできます。

+0

このクエリは少し速く、ありがとう!。しかし、カバー指数は役に立たなかった。 – rpm3948