web-dev-qa-db-ja.com

Postgresで遅いSELECT DISTINCTクエリを高速化するためのソリューション

クエリは基本的に次のとおりです。

SELECT DISTINCT "my_table"."foo" from "my_table" WHERE...

クエリのDISTINCT部分が遅い理由は100%確信しているふりをして、混乱を避けるためにクエリの残りの部分を省略しました。主に関係します(明確なことが常に遅さの原因です)。

問題のテーブルには250万行のデータがあります。 DISTINCTisは、ここにリストされていない目的に必要です(変更されたクエリを戻したくないので、[〜#〜] dbms [〜#〜]レベル、if可能)。

SQLを変更せずに(具体的にはPostgres 9を使用して)DISTINCTをより速く実行するには(つまり、このSQLを変更できませんが、DBレベルで何かを最適化するアクセス権があります)。

25
orokusaki

DISTINCTにより、重複を見つけるために出力行がソートされます。クエリによって選択された列にインデックスを配置すると、データベースはインデックスの順序でそれらを読み取り、ソート手順を保存できる場合があります。多くは、クエリの詳細と関連するテーブルに依存します。「DISTINCTに問題があることを知っている」と言うと、実際に利用可能な回答の範囲が制限されます。

15
antlersoft

多くの場合、distinctを使用してgroup by代わりに:

select my_table.foo 
from my_table 
where [whatever where conditions you want]
group by foo;
28
user554546

データセットのサイズに応じて、work_mem設定を増やすことができます。これにより、クエリプランがハッシュ集計に切り替わり、通常は高速になります。

しかし、グローバルに高く設定する前に、まずそれを読んでください。 max_connections設定はこの数値の乗数として機能するため、サーバーを簡単に爆破できます。

つまり、work_mem = 128MBを設定する場合にmax_connections = 100(デフォルト)を設定すると、12.8GB以上のRAMが必要になります。基本的には、サーバーにクエリの実行にそれだけ使用できることを伝えています(Postgresなどによる他のメモリ使用も考慮していません)。

6
maniek