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

★★★ お知らせ ★★★

◆ 6月のPS Liveは決済サービスStripeのデモ!◆
決済サービスのStripeでサブスクリプションの支払い機能を作ってみた
Stripeの機能の一部を切り出して、簡単なサブスクリプションを作るとどうなるのかを、デモをまじえてご紹介します。
⇒ 詳細はこちらから

◆【セミナー開催】 可視化ツールGrafana~初めてのダッシュボード作成◆
デモンストレーション付き!
本セミナーでは、売上データを用いて、4種類のパネル作成方法をお見せします。
⇒ お申込みはこちらから

◆ エンジニア業務環境アンケート結果 ◆
エンジニアが自分の働き方にどういったことで満足していて、不満を感じているのか、働きたい会社像として何を求めているのか、業務環境調査を実施しました。ぜひご覧ください。
⇒ アンケート結果はこちらから

こんにちは。サイオステクノロジー 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.


*


質問はこちら 閉じる