mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-20 05:17:00 +08:00
Use multi-variate MCV lists to estimate ScalarArrayOpExpr
Commit 8f321bd16c added support for estimating ScalarArrayOpExpr clauses (IN/ANY) clauses using functional dependencies. There's no good reason not to support estimation of these clauses using multi-variate MCV lists too, so this commits implements that. That makes the behavior consistent and MCV lists can estimate all variants (ANY/ALL, inequalities, ...). Author: Tomas Vondra Review: Dean Rasheed Discussion: https://www.postgresql.org/message-id/flat/13902317.Eha0YfKkKy%40pierred-pdoc
This commit is contained in:
@ -827,6 +827,36 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = '
|
||||
343 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
8 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
8 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
26 | 150
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
10 | 100
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
1 | 100
|
||||
(1 row)
|
||||
|
||||
-- create statistics
|
||||
CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists;
|
||||
ANALYZE mcv_lists;
|
||||
@ -872,6 +902,36 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = '
|
||||
200 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
200 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
200 | 200
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
150 | 150
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
100 | 100
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])');
|
||||
estimated | actual
|
||||
-----------+--------
|
||||
100 | 100
|
||||
(1 row)
|
||||
|
||||
-- we can't use the statistic for OR clauses that are not fully covered (missing 'd' attribute)
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL');
|
||||
estimated | actual
|
||||
|
||||
@ -461,6 +461,16 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = '
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])');
|
||||
|
||||
-- create statistics
|
||||
CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists;
|
||||
|
||||
@ -480,6 +490,16 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])');
|
||||
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])');
|
||||
|
||||
-- we can't use the statistic for OR clauses that are not fully covered (missing 'd' attribute)
|
||||
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user