Postgres 9.6 并行 XPath
Postgres 9.6 parallel XPath
我已经设置了 Postgres 9.6 并检查了并行查询工作的大量 table 随机整数。
但是,对另一个 table 的 XML 列的简单 XPath 查询始终是顺序的。这两个 XPath 函数在 Postgres 中都被标记为并行安全的。我试图改变 XPath 成本,因此预期成本猛增,但它并没有改变任何东西。
我错过了什么?
示例table DDL:
CREATE TABLE "test_table" ("xml" XML );
示例查询:
SELECT xpath('/a', "xml") FROM "test_table";
示例数据:
<a></a>
。
请注意,真实数据包含大小为 10-1000kB 的 XML。
> select pg_size_pretty(pg_total_relation_size('test_table'));
28 MB
> explain (analyze, verbose, buffers) select xpath('/a', "xml") from test_table;
Seq Scan on public.test_table (cost=0.00..64042.60 rows=2560 width=32) (actual time=1.420..4527.061 rows=2560 loops=1)
Output: xpath('/a'::text, xml, '{}'::text[])
Buffers: shared hit=10588
Planning time: 0.058 ms
Execution time: 4529.503 ms
这里的相关点可能是 "relation size" 和 "total relation size" 之间的区别:
CREATE TABLE test_table AS
SELECT ('<a>' || repeat('x', 1000000) || '</a>')::xml AS "xml"
FROM generate_series(1, 2560);
SELECT
pg_size_pretty(pg_relation_size('test_table')) AS relation_size,
pg_size_pretty(pg_total_relation_size('test_table')) AS total_relation_size;
relation_size | total_relation_size
---------------+---------------------
136 kB | 30 MB
像这样的大列值不存储在主关系中,而是在评估并行计划时被推送到其关联的 TOAST table. This external storage does not count towards pg_relation_size()
, which is what the optimiser appears to be comparing against min_parallel_relation_size
:
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_relation_size = '144kB';
EXPLAIN SELECT xpath('/a', "xml") FROM test_table;
QUERY PLAN
---------------------------------------------------------------
Seq Scan on test_table (cost=0.00..49.00 rows=2560 width=32)
SET min_parallel_relation_size = '136kB';
EXPLAIN SELECT xpath('/a', "xml") FROM test_table;
QUERY PLAN
------------------------------------------------------------------------------
Gather (cost=0.00..38.46 rows=2560 width=32)
Workers Planned: 1
-> Parallel Seq Scan on test_table (cost=0.00..35.82 rows=1506 width=32)
我已经设置了 Postgres 9.6 并检查了并行查询工作的大量 table 随机整数。 但是,对另一个 table 的 XML 列的简单 XPath 查询始终是顺序的。这两个 XPath 函数在 Postgres 中都被标记为并行安全的。我试图改变 XPath 成本,因此预期成本猛增,但它并没有改变任何东西。 我错过了什么?
示例table DDL:
CREATE TABLE "test_table" ("xml" XML );
示例查询:
SELECT xpath('/a', "xml") FROM "test_table";
示例数据:
<a></a>
。
请注意,真实数据包含大小为 10-1000kB 的 XML。
> select pg_size_pretty(pg_total_relation_size('test_table'));
28 MB
> explain (analyze, verbose, buffers) select xpath('/a', "xml") from test_table;
Seq Scan on public.test_table (cost=0.00..64042.60 rows=2560 width=32) (actual time=1.420..4527.061 rows=2560 loops=1)
Output: xpath('/a'::text, xml, '{}'::text[])
Buffers: shared hit=10588
Planning time: 0.058 ms
Execution time: 4529.503 ms
这里的相关点可能是 "relation size" 和 "total relation size" 之间的区别:
CREATE TABLE test_table AS
SELECT ('<a>' || repeat('x', 1000000) || '</a>')::xml AS "xml"
FROM generate_series(1, 2560);
SELECT
pg_size_pretty(pg_relation_size('test_table')) AS relation_size,
pg_size_pretty(pg_total_relation_size('test_table')) AS total_relation_size;
relation_size | total_relation_size
---------------+---------------------
136 kB | 30 MB
像这样的大列值不存储在主关系中,而是在评估并行计划时被推送到其关联的 TOAST table. This external storage does not count towards pg_relation_size()
, which is what the optimiser appears to be comparing against min_parallel_relation_size
:
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_relation_size = '144kB';
EXPLAIN SELECT xpath('/a', "xml") FROM test_table;
QUERY PLAN
---------------------------------------------------------------
Seq Scan on test_table (cost=0.00..49.00 rows=2560 width=32)
SET min_parallel_relation_size = '136kB';
EXPLAIN SELECT xpath('/a', "xml") FROM test_table;
QUERY PLAN
------------------------------------------------------------------------------
Gather (cost=0.00..38.46 rows=2560 width=32)
Workers Planned: 1
-> Parallel Seq Scan on test_table (cost=0.00..35.82 rows=1506 width=32)