【PostgreSQL】enable_seqscan について検証してみた (その1)

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【6/19開催】Kong Community Japan Meetup #4
本イベントでは、Kong Inc. のVP of ProductであるReza Shafii氏もプレゼンターとして参加。当社からはアーキテクト マネージャーの槌野の登壇が決定!参加無料です!!
https://column.api-ecosystem.sios.jp/connect/kong/1081/

【6/21開催】開発者目線でのSBOMとの向き合い方
SBOMの導入から開発者がSBOMの作成・管理を自動で行っていくための方法(デモ)を紹介します。SBOMを全く知らない人から、開発との統合までを紹介するので様々なレベルの方に学びがあるライブとなる予定です!
https://tech-lab.connpass.com/event/321422/

【7/19開催】現場で役立つAzure神小技10+α 〜生成AI,RAG,コスト削減など旬な技術満載のLT大会〜
Azureの最新技術や実用的な小技を紹介する特別なライトニングトーク大会を開催します!
https://tech-lab.connpass.com/event/319077/

【7/26開催】最適なIaCツールを選ぼう
プロジェクトでのツール選びに困らないための重要な観点をご説明します!
https://tech-lab.connpass.com/event/319532/

こんにちは。サイオステクノロジー OSS サポート担当 Y です。

今回は、PostgreSQL の enable_seqscan について検証を行なってみました。(※以下の内容は CentOS 7.6/PostgreSQL 11.1 にて検証しています。)

■はじめに

今回は enable_seqscan についてのお話です。

PostgreSQL は、基本的に実行計画を自動で作成した上でクエリを実行してくれますが、設定を変更することで特定の実行プランの利用可否 (例: Hash Join は使わない、等) を指定することが可能です。

上記設定は、パラメータ “enable_*” で実行プラン毎に on/off を指定するのですが、一部のパラメータ (enable_material/enable_nestloop/enable_seqscan/enable_sort) には “完全に無効にすることはできない (It is impossible to suppress ~ entirely,)” と記載されています。

例えば、enable_seqscan のドキュメントの記載は以下の様になっています。

enable_seqscan (boolean)

Enables or disables the query planner's use of sequential scan plan types. It is impossible to suppress sequential scans entirely, but turning this variable off discourages the planner from using one if there are other methods available. The default is on.

この “完全に無効にはできない” という部分が少し気になったので、実際に enable_seqscan の設定を変更して検証してみました。

■検証

それではさっそく、検証してみます。

まずは、以下の様なテスト用のテーブルを作成します。

postgres=# CREATE TABLE hoge (a int);
CREATE TABLE
postgres=# 
postgres=# INSERT INTO hoge VALUES (1);
INSERT 0 1
postgres=# 
postgres=# ANALYZE hoge;
ANALYZE
postgres=# 
postgres=# SELECT * FROM hoge;
 a 
---
 1
(1 row)

postgres=# 

enable_seqscan のデフォルト値は “on” (シーケンシャルスキャンが有効) であるため、まずはデフォルト設定のまま EXPLAIN ANALYZE 文にてクエリ “SELECT * FROM hoge” を実行する際の実行プランを表示してみます。

postgres=# SHOW enable_seqscan;
 enable_seqscan 
----------------
 on
(1 row)

postgres=# 
postgres=# EXPLAIN ANALYZE SELECT * FROM hoge;
                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..1.01 rows=1 width=4) (actual time=0.012..0.013 rows=1 loops=1)
 Planning Time: 0.079 ms
 Execution Time: 0.029 ms
(3 rows)

postgres=# 

すると、”Seq Scan on hoge” と出力されており、シーケンシャルスキャンが利用されていることが確認できます。

次に enable_seqscan の値を “off” (シーケンシャルスキャン無効) に設定して、同様に EXPLAIN ANALYZE 文を実行してみます。

postgres=# SET enable_seqscan TO 'off';
SET
postgres=# 
postgres=# SHOW enable_seqscan;
 enable_seqscan 
----------------
 off
(1 row)

postgres=# 
postgres=# EXPLAIN ANALYZE SELECT * FROM hoge;
                                                    QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=10000000000.00..10000000001.01 rows=1 width=4) (actual time=0.016..0.017 rows=1 loops=1)
 Planning Time: 0.063 ms
 Execution Time: 0.033 ms
(3 rows)

postgres=# 

すると、enable_seqscan = off であっても、”Seq Scan on hoge” と出力されており、シーケンシャルスキャンが利用されていることが確認できます。

確かに、”シーケンシャルスキャンを完全に無効にする” ことはできないようです。

また、enable_seqscan が on の場合と off の場合の EXPLAIN ANALYZE の結果を見ると、同じテーブルに対する同じクエリであるにも関わらず、”cost” の値が大きく違っていることが確認できます。

念のため、ANALYZE を実行してから再度 EXPLAIN ANALYZE を実行しても、cost の値は変化しておらず、統計情報の問題では無いようです。

postgres=# ANALYZE hoge;
ANALYZE
postgres=# 
postgres=# SHOW enable_seqscan;
 enable_seqscan 
----------------
 off
(1 row)

postgres=# 
postgres=# EXPLAIN ANALYZE SELECT * FROM hoge;
                                                    QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=10000000000.00..10000000001.01 rows=1 width=4) (actual time=0.008..0.009 rows=1 loops=1)
 Planning Time: 0.084 ms
 Execution Time: 0.026 ms
(3 rows)

このあたりの処理 (enable_seqscan の値を変えると、cost の値が変わる) に “完全に無効にはできない” という部分の仕組みが隠されているよう気ながします。

■最後に

今回は、PostgreSQL のドキュメントに記載されている “enable_seqscan を off に設定してもシーケンシャルスキャンを完全に無効にすることはできない” という内容を実際に検証してみました。

結果として、ドキュメントに記載されている通りシーケンシャルスキャンを完全に無効にすることはできませんでした。また、実行計画を作成する際の “cost” に “完全に無効にできない” とう部分の仕組みがあるように見受けられます。

次回は、enable_seqscan を off に設定した際の処理をもう少し深堀りしてみようと思います。

アバター画像
About サイオステクノロジーの中の人 41 Articles
サイオステクノロジーで働く中の人です。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる