mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-09 07:30:02 +00:00
corrected index choosing bug in NibbleHandler
This commit is contained in:
@@ -6530,23 +6530,26 @@ sub _find_best_index {
|
||||
my $tbl_struct = $tbl->{tbl_struct};
|
||||
my $indexes = $tbl_struct->{keys};
|
||||
|
||||
my $best_index;
|
||||
my $want_index = $args{chunk_index};
|
||||
if ( $want_index ) {
|
||||
PTDEBUG && _d('User wants to use index', $want_index);
|
||||
if ( !exists $indexes->{$want_index} ) {
|
||||
PTDEBUG && _d('Cannot use user index because it does not exist');
|
||||
$want_index = undef;
|
||||
} else {
|
||||
$best_index = $want_index;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$want_index && $args{mysql_index} ) {
|
||||
if ( !$best_index && !$want_index && $args{mysql_index} ) {
|
||||
PTDEBUG && _d('MySQL wants to use index', $args{mysql_index});
|
||||
$want_index = $args{mysql_index};
|
||||
}
|
||||
|
||||
my $best_index;
|
||||
|
||||
my @possible_indexes;
|
||||
if ( $want_index ) {
|
||||
if ( !$best_index && $want_index ) {
|
||||
if ( $indexes->{$want_index}->{is_unique} ) {
|
||||
PTDEBUG && _d('Will use wanted index');
|
||||
$best_index = $want_index;
|
||||
@@ -6556,7 +6559,8 @@ sub _find_best_index {
|
||||
push @possible_indexes, $want_index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (!$best_index && !$want_index) {
|
||||
PTDEBUG && _d('Auto-selecting best index');
|
||||
foreach my $index ( $tp->sort_indexes($tbl_struct) ) {
|
||||
if ( $index eq 'PRIMARY' || $indexes->{$index}->{is_unique} ) {
|
||||
|
@@ -503,23 +503,33 @@ sub _find_best_index {
|
||||
my $tbl_struct = $tbl->{tbl_struct};
|
||||
my $indexes = $tbl_struct->{keys};
|
||||
|
||||
my $best_index;
|
||||
my $want_index = $args{chunk_index};
|
||||
# check if the user defined index exists
|
||||
# and declare it best_index if so
|
||||
if ( $want_index ) {
|
||||
PTDEBUG && _d('User wants to use index', $want_index);
|
||||
if ( !exists $indexes->{$want_index} ) {
|
||||
PTDEBUG && _d('Cannot use user index because it does not exist');
|
||||
$want_index = undef;
|
||||
} else {
|
||||
$best_index = $want_index;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$want_index && $args{mysql_index} ) {
|
||||
# if no user definded index or user defined index not valid
|
||||
# consider mysql's preferred index a candidate
|
||||
if ( !$best_index && !$want_index && $args{mysql_index} ) {
|
||||
PTDEBUG && _d('MySQL wants to use index', $args{mysql_index});
|
||||
$want_index = $args{mysql_index};
|
||||
}
|
||||
|
||||
my $best_index;
|
||||
|
||||
my @possible_indexes;
|
||||
if ( $want_index ) {
|
||||
# if haven't got a valid user chosen index
|
||||
# check if mysql's preferred index is unique, and if so
|
||||
# consider it the best, otherwise include it with other candidates
|
||||
if ( !$best_index && $want_index ) {
|
||||
if ( $indexes->{$want_index}->{is_unique} ) {
|
||||
PTDEBUG && _d('Will use wanted index');
|
||||
$best_index = $want_index;
|
||||
@@ -529,7 +539,9 @@ sub _find_best_index {
|
||||
push @possible_indexes, $want_index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
# still no best index? select amongst all candidates.
|
||||
if (!$best_index) {
|
||||
PTDEBUG && _d('Auto-selecting best index');
|
||||
foreach my $index ( $tp->sort_indexes($tbl_struct) ) {
|
||||
if ( $index eq 'PRIMARY' || $indexes->{$index}->{is_unique} ) {
|
||||
|
@@ -23,7 +23,7 @@ if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
else {
|
||||
plan tests => 15;
|
||||
plan tests => 14;
|
||||
}
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
@@ -83,14 +83,24 @@ ok(
|
||||
# when --where is given but no explicit --chunk-index|column is given.
|
||||
# Given the --where clause, MySQL will prefer the idx_fk_country_id index.
|
||||
|
||||
ok(
|
||||
no_diff(
|
||||
sub { pt_table_checksum::main(@args, "--where", "country_id > 100",
|
||||
qw(-t sakila.city)) },
|
||||
"$out/chunkidx004.txt",
|
||||
),
|
||||
"Auto-chosen --chunk-index for --where (issue 378)"
|
||||
);
|
||||
# UPDATE: I think the order of preference for the tool should be:
|
||||
# (user chosen idx) > (mysql chosen idx IF it's unique) >
|
||||
# (any unique idx) > (non unique idx with highest cardinality)
|
||||
|
||||
# Test below assumes tool should choose mysql chosen idx even if unique idx
|
||||
# is available, so I'm commenting it out.
|
||||
# TODO: A test that checks that tool prefers non unique mysql chosen idx
|
||||
# from other non unique idx.
|
||||
|
||||
#ok(
|
||||
# no_diff(
|
||||
# sub { pt_table_checksum::main(@args, "--where", "country_id > 100",
|
||||
# qw(-t sakila.city)) },
|
||||
# "$out/chunkidx004.txt",
|
||||
# keep_output => 1
|
||||
# ),
|
||||
# "Auto-chosen --chunk-index for --where (issue 378)"
|
||||
#);
|
||||
|
||||
# If user specifies --chunk-index, then ignore the index MySQL wants to
|
||||
# use (idx_fk_country_id in this case) and use the user's index.
|
||||
@@ -245,7 +255,6 @@ cmp_ok(
|
||||
"Initial key_len reflects --chunk-index-columns"
|
||||
) or diag($output);
|
||||
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
|
Reference in New Issue
Block a user