シンプルで正しい
まず、より冗長なのではなく、式を使用してテストケースを簡略化できます。データ型がデフォルトではなく、 ..
である場合は、最初の行に明示的な型キャストが必要です。VALUES
UNION ALL SELECT
integer
text
第二に、aFULL OUTER JOIN
はまったく無意味です。クエリを遅くするだけです。また、いずれかの行が他のテーブルに複数一致する場合、その行はカウントで乗算されます。
WITH t1(col1, col2) AS (VALUES (1, 1), (2, 2), (3, 3))
,t2(col1, col2) AS (VALUES (1, 'A'), (2, 'B'), (2, 'C')) -- 2nd row for "2"
SELECT count(t1.*), count(t2.*)
FROM t1
FULL OUTER JOIN t2 USING (col1);
収量:
4 3
これは間違っています。
WITH t1(col2) AS (VALUES (1), (2), ( 3))
,t2(col2) AS (VALUES ('A'), ('B'), ('C'))
SELECT (SELECT count(*) FROM t1) AS t1_ct
,(SELECT count(*) FROM t1) AS t2_ct;
収量:
3 3
これは正しいですが、よりシンプルで高速です。
確かに、row_number()
新たに適用された場合、重複はあり得ません。しかし、それは時間の無駄です。
パフォーマンス
大きなテーブルの場合、カウントは比較的遅くなります。正確な数は必要ありませんが、見積もりを立てることができる場合は、これを非常に高速に取得できます。
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
ここでマニュアルを引用します:
これは、VACUUM、ANALYZE、およびCREATEINDEXなどのいくつかのDDLコマンドによって更新されます。
この関連する回答の詳細。