PHPerのためのPostgresqlチューニングmini
2021/11/10
株式会社ラクスさま主催
エンジニアの勉強法ハックLT- vol.6
hiro(@etBeEP5e7dwmw7P)
廣川 高久
hiro(@etBeEP5e7dwmw7P)
技術スタック Laravel,vue.js,postgresql
楽しみにしてること
12月からNetflixで始まる COWBOY BEBOP
最近取り組んでいること
・月1回 LT発表
・テストコード(コードカバレッジ、laravel dusk導入)
・Go
アジェンダ
1. トーク[PHPerが知るべきMysqlチューニング] の紹介
2. Postgresqlのチューニング事例
a. パーティション指定
b. 不要データ削除
c. 実行計画の調整
d. INDEXはリリースを考慮してCONCURRENTLY
3. まとめ
みなさん、
PHPerカンファ2021で刺さったテーマは何でしたか?
僕はこちらのトークテーマがぶっ刺さりました
1. スロークエリを改善する理由
2. 現場で起きていること
3. スロークエリの見える化
4. SQLの分析改善手法
5. スロークエリ予防
6. SQLから見える本質
今回は、僕の経験した
Postgresqlチューニングの改善事例を紹介したいと思います
Case1.パーティションテーブルの指定
SELECT * FROM products WHERE name LIKE '%hoge%';
パーティショニングとは、論理的には一つの大きなテーブルであるものを、物理的により小さな
部品に分割することを指します。
Postgresqlドキュメント 5.11. テーブルのパーティショニングより
products products_1
products_3 products_4
products_2
アプリケーションからは、パーティションを意識
せず参照できる
内部的には各パーティションテーブルを READ対象にしてい
て、速度低下を招いていた
Case1.パーティションテーブルの指定
SELECT * FROM products_3 WHERE name LIKE '%hoge%';
products products_1
products_3 products_4
products_2
アプリケーションからも、パーティションを指定
するように変更
一例: 2.4s => 0.8ms へ短縮
下はアプリケーション(Laravel)の実装イメージ
バッチ処理などシステム側で生成するレコードは自動削除するバッチを作っていたが、
一部テーブルは解約者の利用したデータが残っていた
Case2.不要データの削除
ビジネスサイドに確認をとった上で、解約者のデータを削除
4.9億 => 3.6億へ削減
=>コスト削減・読み取り処理の効率化
Case3.実行計画の調整
EXPLAIN ANALYZE SELECT ...;
=> Merge JOIN
SET enable_merge_join = false;
SET enable_seqscan_join = false;
遅いSQLの実行計画を確認したところ、Merge JOINを用いた結合条件がボトルネックになって
いることがわかった。
遅いSELECT文の実行前後にクエリプランの強制処理を実行
タイムアウトしてしまう検索が80s程度に改善!
Case3.実行計画の調整
SET enable_merge_join = false;
SET enable_seqscan_join = false;
SET — 実行時パラメータを変更する
SETコマンドは実行時設定パラメータを変更します。
...略
SETは現行セッションで使用される値にのみ影響することに注意してください。
リファレンス(SQLコマンド SET)
実行計画に関連する設定値一覧について
リファレンス(19.7 問い合わせ計画)
Case4.INDEXはリリースを考慮してCONCURRENTLY
CREATE INDEX CONCURRENTLY xxxxx
通常のインデックス作成処理では、完了するまで対象テーブルへの書き込みはロックされます
リファレンス CREATE INDEXの説明より
既存テーブルにINDEXを追加する時は、ロック取得してしまうとデッドロックリスクがある。
ロックを取得しないCONCURRENTLYオプションを付与
https://www.postgresql.jp/document/12/html/sql-createindex.html
まだまだありますが、
今日はここまで。。。
x
LIMIT句のあるSQLは
SQLを分割
WHEREの条件指定をJOIN句
の結合条件へもってくる
アプリケーション側の
処理を
SQLで(逆もあり)
サブクエリは可能なら
JOINに変更
ORDER BY id + 0
でINDEXを使わせ
ない
みなさんのスロークエリ改善事例があれば、
お話ししてもらえるとありがたいです!
本日もありがとうございました
12/1(水)コードレビューLT会
でお会いしましょう!
資料
画像 : いらすとや
Postgresql リファレンス(日本語)
SlidesCodeHighlighter

PHPerのためのpostgresqlチューニングmini