summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorGuilhem Bichot <guilhem@mysql.com>2009-10-05 22:59:19 +0200
committerGuilhem Bichot <guilhem@mysql.com>2009-10-05 22:59:19 +0200
commit56312dc7cf7cc3be5e510b3ef743cb29d8783b7e (patch)
tree6cab0463ca3fd874c305f3ee285b970919ac1304 /sql
parent42e807783465ea9b3bc60746baafbb07c1462b68 (diff)
downloadmariadb-git-56312dc7cf7cc3be5e510b3ef743cb29d8783b7e.tar.gz
Backport of the fix for BUG#33730 "Full table scan instead selected partitions for query more than 10 partitions"
from 6.0, made in sergefp@mysql.com-20090205190644-q8632sniogedhtsu
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_partition.cc32
1 files changed, 19 insertions, 13 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index f6a8e895fdc..a67ed1cf3af 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6850,7 +6850,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
/* See get_part_iter_for_interval_via_walking for definition of what this is */
-#define MAX_RANGE_TO_WALK 10
+#define MAX_RANGE_TO_WALK 32
/*
@@ -6886,16 +6886,6 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
Intervals with +inf/-inf, and [NULL, c1] interval can be processed but
that is more tricky and I don't have time to do it right now.
- Additionally we have these requirements:
- * number of values in the interval must be less then number of
- [sub]partitions, and
- * Number of values in the interval must be less then MAX_RANGE_TO_WALK.
-
- The rationale behind these requirements is that if they are not met
- we're likely to hit most of the partitions and traversing the interval
- will only add overhead. So it's better return "all partitions used" in
- that case.
-
RETURN
0 - No matching partitions, iterator not initialized
1 - Some partitions would match, iterator intialized for traversing them
@@ -6989,8 +6979,24 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
a += test(flags & NEAR_MIN);
b += test(!(flags & NEAR_MAX));
ulonglong n_values= b - a;
-
- if (n_values > total_parts || n_values > MAX_RANGE_TO_WALK)
+
+ /*
+ Will it pay off to enumerate all values in the [a..b] range and evaluate
+ the partitioning function for every value? It depends on
+ 1. whether we'll be able to infer that some partitions are not used
+ 2. if time savings from not scanning these partitions will be greater
+ than time spent in enumeration.
+ We will assume that the cost of accessing one extra partition is greater
+ than the cost of evaluating the partitioning function O(#partitions).
+ This means we should jump at any chance to eliminate a partition, which
+ gives us this logic:
+
+ Do the enumeration if
+ - the number of values to enumerate is comparable to the number of
+ partitions, or
+ - there are not many values to enumerate.
+ */
+ if ((n_values > 2*total_parts) && n_values > MAX_RANGE_TO_WALK)
return -1;
part_iter->field_vals.start= part_iter->field_vals.cur= a;