首页 > 数据库 > PostgreSQL > 执行计划跑偏,你了解背后的根因吗?
test=> explain analyze select count(*),zone_id from instance_info where instanceid in (SELECT instanceid FROM instance_info wherevisible = 1 GROUPBY instanceid HAVING COUNT(DISTINCT zone_id) > 1) andvisible = 1groupby zone_id; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost=232.45..232.47 rows=1 width=12) (actual time=244941.317..244942.725 rows=4.00 loops=1) Group Key: instance_info.zone_id Buffers: shared hit=3 -> Sort (cost=232.45..232.45 rows=1 width=4) (actual time=244940.890..244941.590 rows=4588.00 loops=1) Sort Key: instance_info.zone_id Sort Method: quicksort Memory: 193kB Buffers: shared hit=3 -> Nested Loop (cost=200.01..232.44 rows=1 width=4) (actual time=124.292..244935.769 rows=4588.00 loops=1) Join Filter: ((instance_info.instanceid)::text = (instance_info_1.instanceid)::text) Rows Removed by Join Filter: 20185277 -> Foreign Scan (cost=100.01..116.12 rows=1 width=146) (actual time=25.421..137.939 rows=2293.00 loops=1) Relations: Aggregate on (instance_info instance_info_1) -> Foreign Scan on instance_info (cost=100.00..116.30 rows=2 width=150) (actual time=1.290..103.183 rows=8805.00 loops=2293) Planning: Buffers: shared hit=173 Planning Time: 1.516 ms Execution Time: 244953.762 ms (17 rows) test=>
test=> set enable_nestloop tooff; SET test=> explain analyze select count(*),zone_id from instance_info where instanceid in (SELECT instanceid FROM instance_info wherevisible = 1 GROUPBY instanceid HAVING COUNT(DISTINCT zone_id) > 1) andvisible = 1groupby zone_id; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost=232.44..232.46 rows=1 width=12) (actual time=273.475..274.907 rows=4.00 loops=1) Group Key: instance_info.zone_id Buffers: shared hit=3 -> Sort (cost=232.44..232.45 rows=1 width=4) (actual time=273.006..273.722 rows=4588.00 loops=1) Sort Key: instance_info.zone_id Sort Method: quicksort Memory: 193kB Buffers: shared hit=3 -> Hash Join (cost=216.13..232.43 rows=1 width=4) (actual time=160.901..271.843 rows=4588.00 loops=1) Hash Cond: ((instance_info.instanceid)::text = (instance_info_1.instanceid)::text) -> Foreign Scan on instance_info (cost=100.00..116.30 rows=2 width=150) (actual time=4.691..109.722 rows=8805.00 loops=1) -> Hash (cost=116.12..116.12 rows=1 width=146) (actual time=156.185..156.186 rows=2293.00 loops=1) Buckets: 4096 (originally 1024) Batches: 1 (originally 1) Memory Usage: 144kB -> Foreign Scan (cost=100.01..116.12 rows=1 width=146) (actual time=21.939..155.037 rows=2293.00 loops=1) Relations: Aggregate on (instance_info instance_info_1) Planning Time: 0.242 ms Execution Time: 287.414 ms (16 rows) test=>

static PathCostComparison
compare_path_costs_fuzzily(Path *path1, Path *path2, double fuzz_factor)
{
#define CONSIDER_PATH_STARTUP_COST(p) \
((p)->param_info == NULL ? (p)->parent->consider_startup : (p)->parent->consider_param_startup)
/* Number of disabled nodes, if different, trumps all else. */
if (unlikely(path1->disabled_nodes != path2->disabled_nodes))
{
if (path1->disabled_nodes < path2->disabled_nodes)
return COSTS_BETTER1;
else
return COSTS_BETTER2;
}
/*
* Check total cost first since it's more likely to be different; many
* paths have zero startup cost.
*/
if (path1->total_cost > path2->total_cost * fuzz_factor)
{
/* path1 fuzzily worse on total cost */
if (CONSIDER_PATH_STARTUP_COST(path1) &&
path2->startup_cost > path1->startup_cost * fuzz_factor)
{
/* ... but path2 fuzzily worse on startup, so DIFFERENT */
return COSTS_DIFFERENT;
}
/* else path2 dominates */
return COSTS_BETTER2;
}
if (path2->total_cost > path1->total_cost * fuzz_factor)
{
/* path2 fuzzily worse on total cost */
if (CONSIDER_PATH_STARTUP_COST(path2) &&
path1->startup_cost > path2->startup_cost * fuzz_factor)
{
/* ... but path1 fuzzily worse on startup, so DIFFERENT */
return COSTS_DIFFERENT;
}
/* else path1 dominates */
return COSTS_BETTER1;
}
/* fuzzily the same on total cost ... */
if (path1->startup_cost > path2->startup_cost * fuzz_factor)
{
/* ... but path1 fuzzily worse on startup, so path2 wins */
return COSTS_BETTER2;
}
if (path2->startup_cost > path1->startup_cost * fuzz_factor)
{
/* ... but path2 fuzzily worse on startup, so path1 wins */
return COSTS_BETTER1;
}
/* fuzzily the same on both costs */
return COSTS_EQUAL;
#undef CONSIDER_PATH_STARTUP_COST
}





来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70033867/viewspace-3107613/ ,如需转载,请注明出处,否则将追究法律责任。