2017-07-13 7 views
0

私は現在、OracleからPostgresSQLへアプリケーションを移植しています。私はOracleと同じ問題を抱えています。これはこれを試して修正する良い時期のようです。 、SQL:この選択クエリを高速化するにはどうすればよいですか?

create table T1(
    id bigserial primary key, 
    a integer, 
    b char(5), 
    c char(2), 
); 

今、すべてのは、今して、私はユニークなA、Bのどのセットを知っておく必要があります。

はとにかく、私はこのようになります/日100kの行を追加すること周り200M行を持つテーブルを持っていますCの値はそうです。そのようなようなクエリが表示されます。私は、テーブルの結合が問題にほとんど関係しないと思うが、私は完全性のためにそれらを含めている。

SELECT DISTINCT A, B, C, T3.N 
    FROM T1 
    JOIN T2 ON T2.ID = T1.A AND T2.NAME = 'FOO' 
    JOIN T3 ON T3.ID = T2.PID 

はまた、このようになりますインデックス:それは代わりにテーブルスキャンのインデックス・スキャンが可能になりますので、

CREATE INDEX I ON T1(A,B,C); 

指数はすでに物事をスピードアップします。

このクエリは通常、約1分かかり、100行未満を返します。私は約1ミリ秒かかると思います。私は素朴な解決策は、これらの値を追跡するための新しいテーブルを作成することだと思うし、T1に新しいレコードを追加するときにそこのA、B、Cタプルだけをチェックし、まれな出来事。これは面倒なようで、2つのテーブルを使用するよりも良い方法があるはずです。

GROUP BYトリックを使用しても、インデックス全体をスキャンしているため、予想どおり、あまり効果がありません。

クエリプランは次のようになります。

enter image description here

我々はT2中での発現が、それはT1のインデックスの巨大な塊をフィルタとして予想通り、かなりの助けに参加することを見ることができます。

+0

結合が不適切であるという前提に従ってクエリプランを共有できますか?実際のクエリプランを見れば、おそらくもっと良い答えを得ることができます。 –

+0

クエリプランが追加されました。あなたが見ることができるようにT2とT3は非常に小さいです。 T2.IDとT3.IDは主キーです。 (これもテストデータで、T1は〜45M行です)。 – Krum

+1

[Materialized Views](https://www.postgresql.org/docs/current/static/rules-materializedviews.html)オプションも試しましたか? –

答えて

-1

さらに多くのインデックスを使用することを検討してください。データにリンクするすべての方法のインデックスがあることを確認してください。

たとえば、T2.IDのt2にリンクします。だから、複合インデックスではなくT2.idだけのインデックスがあることを確認してください。

一般に、フィルタリングしているテーブルでは、星印を付ける方が高速です。 T2.NAME = 'FOO'でフィルタリングしていて、内部結合を使用しています。

したがって、T2で始まり、T1に参加してからT3に参加してください。

また、T3のインデックスをT3.IDに、もう1つのインデックスをT1.Aに設定します。

これにより、クエリで検索する必要がある行数が制限されます。 T2のレコードはNAME = 'FOO'のT3とT1にのみリンクされます。したがって、クエリの総作業負荷を大幅に削減できます。

+0

これは助けにならないランダムなアドバイスです:「T3.IDにT3のインデックスを置く」 - それは既にインデックス(「インデックスのみのスキャン」を参照)、「T1.Aの別のインデックス」 - 役に立たないすでに索引付けされています( '(A、B、C)'に索引があるので、 'a 'に別の索引は必要ありません)。 – Nick

+0

クエリで使用していると思われるインデックスが使用されているかどうかを確認する必要があります。私はあなたがこの考え方に誤りがあるかもしれないと思います。すべての結合で索引が使用されていることを確認してください。 –

関連する問題