性能要件

性能要件にスループットが入ることはよくあります。
スループットとは、何秒以内に処理できるや同時アクセス数が最大〇〇件までは対応できるなどです。
データベースで対応させるには、インデックスやパラメータのチューニングも考えられます。
限界がありますので、高スペックのサーバを使用したり、複数台のサーバで負荷分散をすることを検討するの考えられることです。

DBMSで検討するにはサーバの性能もそうですが、1箇所に集約して管理する集中型と複数の拠点に設置してデータを同期しながら管理する分散型があります。
集中型のことをシェアードエブリシングといい、分散型をシェアードナッシングといいます。
分散型は集中型に比べて以下メリットがあります。

[メリット]
・読み取りだけであれば、別々のデータベースが応答可能なため負荷分散・アクセス向上
・東京A店データベース、北海道B店データベースなどとしたときに北海道B店で問題が発生しても東京A店は継続可能
・ディスクがクラッシュしたなどでデータが参照できなくても別のデータベースで保持
しかし、分散型は以下デメリットもあります。
[デメリット]
・コスト増加
・書込遅延(2相コミット:データ書込時に各データベースに書き込めるかの確認が必要で書込み可能ならコミットするができない場合はロールバック) ・管理の複雑化(各データベースの障害発生・各データベースへの接続失敗などの処理)
また、分散型ではコストが増加して複雑になり、透過性(位置・移動・分割・重複・障害)も意識する必要があります。
分散型でいう透過性は、分散型データベースが複数のサーバになりその接続先、データ保存・重複格納・分割格納、障害発生を意識することなく利用者が利用できることです。

性能チューニング

性能をチューニングするには、ボトルネックを発見してそれに対して改善することです。
データベースでは、再編成と再構成があります。

[再編成]
レコードの追加・削除を繰り返すと、ファイルに断片的で使用できないデータ格納領域を再配置することです。

[再構成]
スキーマの変更、インデックス・カラム追加などを行うことです。

PostgreSQLはクエリ実行時、以下のフローで動作します。


(4)の段階でインデックスを利用した方がよいと判断したら、インデックスを利用しますが、そうでない場合はシーケンシャルスキャンします。
また、インデックスが利用されないなどの場合は、以下が考えられます。
・統計情報が正しく更新されていない:統計情報更新(vaccum,analyz)
→大量のデータのインサートや削除などをしている場合は可能性大
・インデックス破損:インデックスを作成しなおす(reindex)

プランナーが利用するものを強制的に変更(pg_hint_plan)することも可能です。
(random_page_costの値が小さく設定またはeffective_cache_sizeを大きく設定)

これを確認するには、クエリの前に「EXPLAIN」をつけます。EXPLAINだけでは確認までしかせず、ANALYZEをつけると実際に実行までします。
Explain
これでも性能が改善しない場合、以下で改善しないかも確認します。

・ファイル断片化がされているため再編成
→アップデートが多いと一つのレコードが一つのファイルに収まらずポインターで別のファイルを参照している可能性があり、それの改善(VACCUM FULL)
・OS並びにPostgreSQLのメモリ設定チューニング
→JOIN,SORTなどはpostgresql.confメモリ設定を確認
設定で改善しない場合はコストも垣間見て以下を検討してみてください。
データと取り込みであれば、insertでデータを挿入せずにCOPYを使用することで高速に取り込むことも可能です。
以下ならコミットするまでログに書きません。
begin;
create table test ...;
copy test from...;
commit;

また、postgres.confで以下を修正することで改善します。

性能計測

データベースで性能を計測するにあたり、実行クエリが期待通りの秒数で完了していないことを確認(ベンチマーク)したり、サーバのリソースが十分であるかを確認します。

pgAdminのダッシュボードでPosstgreSQLのセッション数やトランザクション数を確認できます。
pgadmin4ダッシュボード

サーバのリソースが不足していれば性能はでません。
運用していてCPUの使用率が高くなってなかったり、メモリが不足してしまいディスクを利用する問題(スラッシング)が発生していなかったりするなど運用していてサーバのスペックが十分であるか確認します。
何がボトルネックになっているのかが重要になります。(CPU使用率が高いがメモリが不足しているのが原因でメモリがボトルネックなど)
全ての性能を向上すれば性能はあげられるかもしれませんが、不要なものをあげてもただのコストアップにしかならないです。
また、サーバのリソースが不足していてもPostgreSQLの設定で改善できる場合もあります。
それは、チューニングで記載します。
OSがLinuxですが、以下が確認コマンドです。

[確認コマンド]

一般的に書き込みバッファを持つディスク装置と大容量の仮想メモリを割り当てたOSを使用すれば性能は向上します。

チューニングに記載しますが、クエリのベンチマークをPosstgreSQLで計測するには「EXPLAIN」を利用します。
EXPLAINを利用するとどれぐらいの件数がどれぐらいの速度で表示できるか確認できます。
また、チェックポイント発生状況、キャッシュヒット率、デッドロックなど

インデックス(索引)

インデックスとは辞書でいうところの索引にあたり目的のデータを高速に探せるようにするためのものです。
必ず使わなくてはいけないものではありませんが、検索の性能改善では利用するのが好ましいです。
データを特定するためのキー(インデックス)として登録することでデータを効率よく利用できます。

インデックスはカーディナリティが高い場合に有効で、カーディナリティ高いとは会員番号・名前などたくさんの種類があるデータでカーディナリティ低いとは性別・真偽値など少ない種類のデータです。

インデックスが利用される場合は、全てのページを読み込む必要はなく必要なページだけを読み込みますので探索が早く読み込むページ数が少なくなりメモリの削減につながります。
インデックスが利用されない検索の場合、全行を一から総なめするシーケンシャルスキャンが利用されます。
シーケンシャルスキャンとは、全データを上から順番に検索します。
そのため、最悪の場合は検索しているテーブルの前ページを読み込む必要が発生してしまい、無駄なメモリを利用することが考えられます。

但し、インデックスを追加すればデータとは別にインデックスのデータが必要になり、データ量が増加してInsert・Updateなどの性能が低下することも注意が必要です。

PostgreSQLにはHOT(Heap Only Tuple)があり、UPDATE時にインデックスの更新は行わずにポイント参照をすることで更新性能を向上させます。
HOTが有効になるのは、ページ内に空き領域(FILLFACTER)が必要で、削除してからの追加や大量の更新などでは動作しませんので注意が必要です。

データベーススペシャリストでは、主索引と副次索引と複合索引と呼ばれる索引があります。
主索引は主キーに対して付けるインデックスでキー順にページが読まれて、副次索引は主キー以外に対して付けるインデックスで行をランダムなページで読みます。
複合索引は複数の列に付けるインデックスです。

インデックスといっても種類があり、B⁺木インデックスが一般的ですが、次にインデックスの種類を記載します。