web-dev-qa-db-ja.com

新しいハードウェアと最新バージョンのPostgreSQLでは、多くのクエリが遅くなります

注:コメンテーターが私を導いた方向性とその過程で学んだことを基に、この質問を大幅に作り直しました。

新しい開発データベースサーバーをセットアップしています。新しいものは、16GB DDR4メモリを搭載した第6世代i7-6700とPostgreSQL 9.6を搭載したIntel 750 SSDです。古いものは、第4世代のi5-4570で、16 GB DDR3メモリと、PostgreSQL 9.2を搭載したCrucial SSD Raid 0アレイを備えています。私は750をベンチマークしました、そしてそれはRAIDよりもずっと速いです。ただし、256KB未満の読み取りパフォーマンスは遅くなります。

_pg_dump_および_pg_restore_を使用してデータを移動し、すべてのデータベースで_vacuum analyze_を実行しました。

新しいコンピューターは古いコンピューターよりもかなり高速である必要があり、クエリの種類によってはそうなりますが、他のコンピューターでは数倍遅くなります。新しいコンピューターに9.2をインストールして、データベースのバージョンをハードウェアから分離しようとしました。私は_postgresql.conf_を可能な限り同一に保ちました(9.6はいくつかのwal設定を変更します。)

問題を絞り込むための統計情報を取得するために_pg_stat_statements_を設定しました。 500以上のスキーマと3000以上のテーブルがあります。私が実行している変換は、これらのテーブルのいくつかから新しいテーブルを作成し、これらの3000の他のテーブルからそれらの新しいテーブルを更新しています。私はこの50GBのデータ全体をバウンスしています。

新しいサーバーと9.6で_create table_、copyvacuumanalyze、_drop table_、多くの行に影響する更新、_create index_ 、_create table as_は通常、最大で2倍高速です。しかし、時々それらは数倍遅くなります。 9.2を実行している新しいサーバーも同様のパターンに見えますが、パフォーマンスの向上はそれほど顕著ではありません。興味深いことに、特定のcopyまたはvacuumで9.6が遅い場合、9.2は通常通常も遅くなります。

いくつかの行を返す_drop index_、_drop table_、selectクエリ、単一の行に影響を与えるselect count(*)updateクエリはすべて通常50%-新しい9.6サーバーでは300%遅くなります。新しいサーバーの9.2も低速ですが、通常は20%〜30%です。 PostgreSQLがディスクにアクセスする方法はわかりませんが、小さいファイルでのIntel 750の遅い読み取りパフォーマンスは、遅い9.2の速度で見られるように効果があると思います。ただし、同じサーバーでの9.2と9.6の間の5x-10xパフォーマンスの低下については説明していません。

したがって、私の結論は、特定のタイプのクエリでは9.6が大幅に遅いということです。

問題のクエリの多くについて説明を実行しましたが、計画は同じです。

遅いクエリの代表的な例をいくつか示します(_pg_stat_statements_から)。これらはすべて主キーであり、インデックスが付けられてバキューム処理され、分析されていること、および2つのデータベース間で同一であることに注意してください。また、少なくとも50回の呼び出しがあるクエリのみを選択しました。

_Update finalal Set jsondone=?, json=? Where id=? //20% slower
SELECT * FROM archive_natrilis_2015_q3.natrilis_releases WHERE siteid = ? ORDER BY reporting_year ASC LIMIT ? // 404% slower
SELECT * FROM work_narcra00_2016_q3.narcra_handler WHERE siteid = ? ORDER BY handler_sequence_number ASC LIMIT ? // 182% slower
select * from listtypedesc // small 20 row table, 173% slower.
select * from INFORMATION_SCHEMA.schemata where schema_name not like ? and schema_name not like ? AND schema_name like ? Order by schema_name Desc // 52% slower
Select count(*) From work_allustis_2016_q3.allustis_details Where siteid = ? // 234% slower
SELECT * FROM archive_naerns14_2015_q2.naerns14_material_involved WHERE siteid = ?  LIMIT ? // 287% slower
_

私の結論は正しいですか?そしてもしそうなら、これらの遅いクエリを最適化するための9.6固有の方法はありますか?そうでない場合、推奨する他のデバッグアクションはありますか?

4
Brad Mathews

一度に変更したものが多すぎます。最初に新しいハードウェアで9.2を実行し、パフォーマンスを確認します。それを整理したら、9.6にアップグレードします。

データをどのように移動しましたか?論理的には、pg_dumpを使用してから復元を使用するか、物理的にpg_basebackup(またはコールドコピー)を使用してからpg_upgradeを使用しますか?

最終セットを更新jsondone = 1 Where id = 1

古いサーバーは、72回の反復で平均0.2ミリ秒でこれを実行します。新しいサーバーは1.43msです。

同じid =?の72回の反復値、または連続したもの、またはランダムなものですか?そして、すべてが1つのトランザクションで行われるのか、それとも個別のトランザクションで行われるのか

新しいサーバーはコストの半分(ただし、何らかの理由で起動コストが高くなっています)を示しているため、特に高速のハードウェアでは高速になると思います。

これらのコストは一般的な時間の見積もりではなく、合理的なプランナーの選択を行うために使用される内部会計です。選択肢のないもの(行を更新する唯一の方法がある)はまったくコストがかかりませんが、明らかに実際に時間がかかります。そしてそれを念頭に置いても、バージョン間でそれらを比較する場合は十分に注意する必要があります。それらはその目的のためだけのものではありません。

新しいサーバーでは、shared_blks_readとshared_blks_dirtiedの高さが約2倍であることに気付きました。 shared_blks_hitはわずかに高くなっています。多分それの手掛かりかもしれませんが、私はこれが意味することを本当に知りません。

これは、物理サーバーではなくpg_dumpを使用してデータを取得したためか、新しいサーバーのデータが古いサーバーよりも密にパックされていることを意味しています。テーブルのデフォルトのfillfactorは100%であるため、行はできるだけ多くのページにパックされます。

したがって、古いサーバーで更新を行うと、更新された行の新しいバージョンを古いバージョンと同じページに配置する余地があります。新しいサーバーでは、ページにスペースがないため、新しいバージョンの行を配置するために別のページを探す必要があります(そうすると、両方のページが汚れます)。つまり、インデックスを更新する必要があるため、新しいバージョンの場所がわかります。

2
jjanes