postgreSQLデータベースの2つのテーブル間で左結合を実行しようとしていますが、実行に約14分かかることがわかりました。既存のSO投稿から、このタイプの結合は数秒のオーダーである必要があるように思われるので、この結合のパフォーマンスを向上させる方法を知りたいと思います。を使用して、w /のマシンで実行64-bit
postgreSQL version 9.4.4
しています。テーブルの構造は次のとおりです。Windows 8
8 GB RAM
pgAdmin III
表A:「parcels_qtr」:
小包(テキスト)| 年(int)| qtr(テキスト)| lpid(pk、text)|
1,550万行あり、各列にインデックスが付けられ、「lpid」が主キーです。また、このテーブルを標準の真空プロセスで実行しました。
表B:「postalvac_qtr」:
小包(テキスト)| 年(int)| qtr(テキスト)| lpid(pk、text)| vacCountY(int)|
618,000のレコードがあり、「vacCountY」を除くすべてのフィールドにインデックスが付けられ、「lpid」が主キーです。これも標準的な真空プロセスを経ています。
データ出力で実行する場合、約14分かかります。一緒explain (analyze, buffers)
に実行すると、1分強かかります。最初の質問-このパフォーマンスの違いは完全にデータの印刷に起因するのでしょうか、それともここで何か他のことが起こっているのでしょうか?
そして2番目の質問ですが、この実行時間を数秒に短縮できますか?
これが私のSQLコードです:
EXPLAIN (ANALYZE, BUFFERS)
select a.parcel,
a.lpid,
a.yr,
a.qtr,
b."vacCountY"
from parcels_qtr as a
left join postalvac_qtr as b
on a.lpid = b.lpid;
そして、これが私の説明文の結果です:https://explain.depesz.com/s/uKkK
私はpostgreSQLにかなり慣れていないので、忍耐と説明をいただければ幸いです。
あなたはDBにかなりの仕事をするように頼んでいます。説明プランを見るだけで、次のようになります。
postalvac_qtr
)lpid
parcels_qtr
)lpid
ハッシュし、既存のハッシュテーブルと照合しますこれらのテーブルの大きさはどれくらいですか?これを確認するには、次を発行します。
SELECT pg_size_pretty(pg_relation_size('parcels_qtr'));
このハッシュ結合がディスクに流出していることはほぼ確実であり、その構造化(「これらの両方のテーブルからのすべてのデータを提供してください」)では、そうならない方法はありません。
インデックスは役に立ちませんし、できません。テーブル全体を要求している限り、インデックスを使用すると処理が遅くなるだけです。postgresはとにかくテーブル全体をトラバースする必要があるため、シーケンシャルスキャンを発行することもできます。
クエリのパフォーマンスがと異なる理由については、explain analyze
あなたが正しいと思います。1-クライアントに1500万行を送信することと、2-それを表示しようとすることの組み合わせは、実際のクエリを超えて大幅な速度低下を引き起こします。
それで、あなたはそれについて何ができますか?
まず、このクエリは何をしようとしていますか?完全にフィルタリングされていない、これら2つのテーブルのすべてのデータを取得する頻度はどれくらいですか。それが非常に一般的である場合は、要件の段階に戻って、そのニーズに対処する別の方法を考え出すことを検討することをお勧めします(たとえば、特定の年と四半期のすべてのデータを取得するのが合理的でしょうか?)。それが一般的でない場合(たとえば、毎日のエクスポート)、1〜14分で十分な場合があります。
次に、テーブルが肥大化していないことを確認する必要があります。あなたは重要な発生した場合update
やdelete
、あなたのテーブルの上のトラフィックを、それは時間をかけて、それらを成長することができます。autovacuumデーモンはこれに対処するのに役立ちますが、場合によってはvacuum full
willを発行することも役立ちます。
第三に、DB構成の調整を試すことができます。にはpostgresql.conf
、サーバーがディスクキャッシュに使用できるRAMの予想量や、サーバーが並べ替えや結合に使用できるRAMの量(ディスクに流出する前)などのパラメーターがあります。これらの種類のパラメータをいじることで、速度を向上させることができるかもしれません。
第4に、スキーマを再検討することをお勧めします。年と四半期を2つの別々の列として使用しますか、それともこのdate
タイプの単一の列を使用する方がよいでしょうか。あなたがしたいですかtext
キーを、またはあなたがより良いオフとなりますbigint
(シリアルまたは由来のいずれかのtext
可能性がより迅速に加わるであろう、列)?あるparcel
、yr
とqtr
フィールドは、実際に両方のテーブルに必要な、またはそれらが一つのテーブルにデータを複製していますか?
とにかく、これがお役に立てば幸いです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加