PostgreSQLの珍しい実行計画はAurora DSQLでも出現するのか確認してみた

PostgreSQLの珍しい実行計画はAurora DSQLでも出現するのか確認してみた

色々なSQLを試すとPostgreSQL非互換の部分が見えて面白かったです
Clock Icon2024.12.15

リテールアプリ共創部@大阪の岩田です。

以前Zennで読んだ以下の記事が「面白いな〜」と印象に残っていたのですが、これらの実行計画はAurora DSQLでも利用可能なのか気になったので試してみました。

https://zenn.dev/forcia_tech/articles/20240607_yoshida_plannode

やってみる

それではさっそく試していきましょう。以下のSQLは全てadminユーザーで実行しています。

テーブルの作成

まず元記事にならって以下のDDLでテーブルを作成します。

create table hoge (id int primary key, val int);

準備ができたら色々SELECT文を実行していきます。

10位: LockRows

まずはLockRowsを試してみましょう。

explain select * from hoge for update;

実行すると以下のエラーが出ました。

ERROR:  locking clause such as FOR UPDATE can be applied only on tables with equality predicates on the key

エラーメッセージからするとキーを指定すればいけそうですね。このエラーについては以下のAWSブログでも紹介されていました。

https://aws.amazon.com/blogs/database/concurrency-control-in-amazon-aurora-dsql/

ということでWHERE句を追加してリトライしてみました。

explain select * from hoge where id  = 1 for update;

結果は以下の通りです。

                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 LockRows  (cost=100.17..208.19 rows=1 width=24)
   ->  Index Scan using hoge_pkey on hoge  (cost=100.17..208.18 rows=1 width=24)
         Index Cond: (id = 1)
         Projected via pushdown compute engine: id, val
(4 rows)

LockRowsが出現しました!Aurora DSQLは楽観的同時実行制御を利用するためロックは取得しないはずなのですが、実行計画としてはLockRorwsが存在するようです。この実行計画が現れた場合はミスリードしないように注意が必要そうです。

9位: Sample Scan

続いてSample Scanです。

explain select * from hoge tablesample system(10);

結果は以下の通りでした。

ERROR:  Sampling is not supported

Aurora DSQLではサンプリングの機能がサポートされていないようです。

8位: MixedAggregate

続いてMixedAggregateです。

explain select id from hoge group by grouping sets(id, ());

結果は以下の通りでした。

                                           QUERY PLAN                                            
-------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=125100.05..183600.06 rows=1000001 width=4)
   Group Key: id
   Group Key: ()
   ->  Index Only Scan using hoge_pkey on hoge  (cost=125100.05..171100.05 rows=1000000 width=4)
         Projected via pushdown compute engine: id
(5 rows)

クエリはエラーなく実行できましたが、実行計画にMixedAggregateは出現しませんでした。

7位: HashSetOp

続いてHashSetOpです。

explain select id from hoge except select id from fuga;

実行結果は以下の通りでした。

                                                 QUERY PLAN                                                  
-------------------------------------------------------------------------------------------------------------
 HashSetOp Except  (cost=125100.05..377200.10 rows=1000000 width=8)
   ->  Append  (cost=125100.05..372200.10 rows=2000000 width=8)
         ->  Subquery Scan on "*SELECT* 1"  (cost=125100.05..181100.05 rows=1000000 width=8)
               ->  Index Only Scan using hoge_pkey on hoge  (cost=125100.05..171100.05 rows=1000000 width=4)
                     Projected via pushdown compute engine: id
         ->  Subquery Scan on "*SELECT* 2"  (cost=125100.05..181100.05 rows=1000000 width=8)
               ->  Index Only Scan using fuga_pkey on fuga  (cost=125100.05..171100.05 rows=1000000 width=4)
                     Projected via pushdown compute engine: id
(8 rows)

HashSetOpが出現しました!なんか嬉しいです。

6位: Table Function Scan

続いてTable Function Scanです。

explain
select *
from xmltable(
  '/rows/row'
  passing
  $$
  <rows>
  <row id="1"></row>
  </rows>
  $$
  columns id int path '@id'
);

実行結果は以下の通りでした。

ERROR:  unsupported XML feature
LINE 6:   $$
          ^
DETAIL:  This functionality requires the server to be built with libxml support.

xmltableがサポートされていないようです。

5位: Foreign Update

続いてForeign Updateです。まずpostgres_fdwを利用可能にするところからです。

create extension postgres_fdw;

実行結果は以下の通りでした。

ERROR:  unsupported statement: CreateExtension

公式ドキュメントにも記載されていますがAurora DSQLはCREATE EXTENSIONに未対応とのことです。

https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-unsupported-features.html#working-with-postgresql-compatibility-unsupported-expressions

4位: Foreign Delete

Foreign Updateと同様にForeign Data WrapperがサポートされていないためAurora DSQLではこの実行計画が出現することはできなさそうです。

3位: Tid Range Scan

続いてTid Range Scanです。

insert into hoge select generate_series(1,10000);
analyze hoge;
explain select * from hoge where ctid < '(1,0)';

実行結果は以下の通りでした。

ERROR:  cannot retrieve a system column in this context

Aurora DSQLではPostgreSQLと違ってctidという概念が無いのかもしれません。一応以下のSQLも試してみます。

select ctid from hoge where id = 1;

結果は変わらず以下の通りでした。

ERROR:  cannot retrieve a system column in this context

そもそもAurora DSQLにはctidという概念が存在しないのか、それともユーザーには隠蔽されているだけなのか...この辺は内部実装の妄想が捗って面白いですね。

ちょっと脱線しますがOIDという概念はあるのか気になったので、こちらも試してみました。

SELECT oid, relname, relnamespace, relowner FROM pg_class;

結果は以下の通りでした。

  oid  |                    relname                     | relnamespace | relowner 
-------+------------------------------------------------+--------------+----------
  1247 | pg_type                                        |           11 |       10
  1249 | pg_attribute                                   |           11 |       10
  1255 | pg_proc                                        |           11 |       10
...略  

この辺は通常のPostgreSQLと同じなんですね。

2位: Foreign Insert

Foreign Updateと同様に...(以下略)

1位: Named Tuplestore Scan

最後はNamed Tuplestore Scanです。まずユーザー定義関数の作成を試みます。

create function copy_inserted() returns trigger as $$
begin
    if (tg_op = 'INSERT') then
        execute 'insert into fuga select * from new_table';
    end if;
    return null;
end;
$$
language plpgsql;

結果は以下の通りでした。

ERROR:  CREATE FUNCTION with language plpgsql not supported

Aurora DSQLではユーザー定義関数が使えないようです。

とりあえず文法的に通るか確認するためにトリガーの作成も試みました。

create trigger copy_hoge_insert_to_fuga
after insert on hoge
referencing new table as new_table
for each statement execute procedure copy_inserted();

結果は以下の通りでした。

ERROR:  unsupported statement: CreateTrig

create triggerを実行したのですが、CreateTrigはサポートしてないというエラーが出ました。SQLのパースに失敗してるんですかね?まあいずれにせよ公式ドキュメントにもトリガーは未サポートと記載してあるので実行計画にNamed Tuplestore Scanが出現することは無さそうです。

まとめ

PostgreSQLの珍しい実行計画がAurora DSQLにも出現するのか確認してみました。今回の検証では以下の実行計画のみ出現を確認できました。

  • LockRows
  • HasSetOp

その他の実行計画については前提となる機能がAurora DSQLではサポートいないなどの理由から出現を確認できませんでした。今後GAまでに追加の機能サポートがあれば今回出現しなかった実行計画も確認できるようになるかもしれませんね。いずれにせよAurora DSQLとPostgreSQLの互換性について確認する良い機会になりました。みなさんもぜひ色々なSQLを試して理解を深めてみて下さい。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.