mirror of https://github.com/citusdata/citus.git
So far citus used postgres' predicate proofing logic for shard pruning, except for INSERT and COPY which were already optimized for speed. That turns out to be too slow: * Shard pruning for SELECTs is currently O(#shards), because PruneShardList calls predicate_refuted_by() for every shard. Obviously using an O(N) type algorithm for general pruning isn't good. * predicate_refuted_by() is quite expensive on its own right. That's primarily because it's optimized for doing a single refutation proof, rather than performing the same proof over and over. * predicate_refuted_by() does not keep persistent state (see 2.) for function calls, which means that a lot of syscache lookups will be performed. That's particularly bad if the partitioning key is a composite key, because without a persistent FunctionCallInfo record_cmp() has to repeatedly look-up the type definition of the composite key. That's quite expensive. Thus replace this with custom-code that works in two phases: 1) Search restrictions for constraints that can be pruned upon 2) Use those restrictions to search for matching shards in the most efficient manner available: a) Binary search / Hash Lookup in case of hash partitioned tables b) Binary search for equal clauses in case of range or append tables without overlapping shards. c) Binary search for inequality clauses, searching for both lower and upper boundaries, again in case of range or append tables without overlapping shards. d) exhaustive search testing each ShardInterval My measurements suggest that we are considerably, often orders of magnitude, faster than the previous solution, even if we have to fall back to exhaustive pruning. |
||
---|---|---|
.. | ||
colocation_utils.c | ||
create_shards.c | ||
deparse_shard_query.c | ||
distribution_metadata.c | ||
fake_fdw.c | ||
generate_ddl_commands.c | ||
metadata_sync.c | ||
prune_shard_list.c | ||
test_helper_functions.c |