[PoC] Asynchronous execution again (which is not parallel) - Mailing list pgsql-hackers
From | Kyotaro HORIGUCHI |
---|---|
Subject | [PoC] Asynchronous execution again (which is not parallel) |
Date | |
Msg-id | 20151130.214734.41704526.horiguchi.kyotaro@lab.ntt.co.jp Whole thread Raw |
Responses |
Re: [PoC] Asynchronous execution again (which is not parallel)
Re: [PoC] Asynchronous execution again (which is not parallel) |
List | pgsql-hackers |
Hello, the parallel scan became to work. So I'd like to repropose the 'asynchronous execution' or 'early execution'. In previous proposal, I had only foreign scan as workable example, but now I can use the parallel execution instead to make this distinctive from parallel execution itself. I could put more work on this before proposal but I'd like to show this at this time in order to judge wheter this deserves further work. ==== Overview of asynchronos execution "Asynchronous execution" is a feature to start substantial work of nodes before doing Exec*. This can reduce total startup time by folding startup time of multiple execution nodes. Especially effective for the combination of joins or appends and their multiple children that needs long time to startup. This patch does that by inserting another phase "Start*" between ExecInit* and Exec* to launch parallel processing including pgworker and FDWs before requesting the very first tuple of the result. ==== About this patch As a proof of concept, the first tree patchs adds such start phase to executor and add facility to trace node status for almost all kind of the executor nodes (Part of this would be useless, though). Then the two last implement an example usage of the infrastracture. The two introduced GUCs enable_parasortmerge and enable_asyncexec respecively controls whether to use gather for sorts under merge join and whether to make asyncronous execution effective. For evaluation, I made merge join to use bgworker for some codition as an example. It is mere a mock implement but enough to show the difference between parallel execution and async execution (More appropriate names are welcome) and its effectiveness. Thanks for Amit's great work. ==== Performance test Apply all the patches then do the following in order. Of course this test is artificially made so that this patch wins:) CREATE TABLE t1 (a int, b int); CREATE TABLE t2 (a int, b int); CREATE TABLE t3 (a int, b int); INSERT INTO t1 (SELECT (a / 1000) + (a % 1000) * 1000, a FROM generate_series(0, 999999) a); INSERT INTO t2 (SELECT (a / 1000) + (a % 1000) * 1000, a FROM generate_series(0, 999999) a); INSERT INTO t3 (SELECT (a / 1000) + (a % 1000) * 1000, a FROM generate_series(0, 999999) a); ANALYZE t1; ANALYZE t2; ANALYZE t3; SET enable_nestloop TO true; SET enable_hashjoin TO true; SET enable_material TO true; SET enable_parasortmerge TO false; SET enable_asyncexec TO false; EXPLAIN (COSTS off, ANALYZE) SELECT * FROM t1 JOIN t2 ON (t1.a = t2.a) JOIN t3 on (t1.a = t3.a) ORDER BY t1.a LIMIT 10; SET enable_nestloop TO false; SET enable_hashjoin TO false; SET enable_material TO false; EXPLAIN (COSTS off, ANALYZE) SELECT * FROM t1 JOIN t2 ON (t1.a = t2.a) JOIN t3 on (t1.a = t3.a) ORDER BY t1.a LIMIT 10; SET enable_parasortmerge TO true; EXPLAIN (COSTS off, ANALYZE) SELECT * FROM t1 JOIN t2 ON (t1.a = t2.a) JOIN t3 on (t1.a = t3.a) ORDER BY t1.a LIMIT 10; SET enable_asyncexec TO true; EXPLAIN (COSTS off, ANALYZE) SELECT * FROM t1 JOIN t2 ON (t1.a = t2.a) JOIN t3 on (t1.a = t3.a) ORDER BY t1.a LIMIT 10; ==== Test results On my environment, the following results were given. - The first attempt, planner chooses hash join plan and it takes about 3.3s. - The second, Merge Joins are done in single backend, takes about 5.1s. - The third, simply use parallel execution of MJ, takes about 5.8s - The fourth, start execution asynchronously of MJ, takes about 3.0s. So asynchronous exeuction at least accelerates parallel execution for this case, even faster than the current fastest (maybe) plan. ====== TODO or random thoughts, not restricted on this patch. - This patch doesn't contain planner part, it must be aware of async execution in order that this can be in effective. - Some measture to control execution on bgworker would be needed. At least merge join requires position mark/reset functions. - Currently, more tuples make reduce effectiveness of parallel execution, some method to transfer tuples in larger unit wouldbe needed, or would be good to have shared workmem? - The term "asynchronous execution" looks a little confusing with paralle execution. Early execution/start might be usablebut I'm not so confident. Any suggestions? thoughts? I must apologize for the incomplete proposal and cluttered thoughts. regards, -- Kyotaro Horiguchi NTT Open Source Software Center
pgsql-hackers by date: