Fix to optimize getting table index stats for large tables

This commit is contained in:
Ilia Ross 2024-07-26 19:56:45 +03:00
parent a9ed10401d
commit b03f1b766f
No known key found for this signature in database
GPG Key ID: 121E166DD9C821AB
2 changed files with 61 additions and 1 deletions

View File

@ -117,9 +117,11 @@ elsif (@titles || @indexes) {
local @str = &table_structure($in{'db'}, $t);
push(@fields, scalar(@str));
}
my $table_index_stats = &get_table_index_stats($in{'db'});
foreach $t (@indexes) {
push(@types, $text{'dbase_typeindex'});
$str = &index_structure($in{'db'}, $t);
$str = &parse_index_structure($table_index_stats,
$in{'db'}, $t);
push(@rows, "<i>$text{'dbase_index'}</i>");
push(@fields, scalar(@{$str->{'cols'}}));
}

View File

@ -1304,6 +1304,37 @@ return &ui_textbox($name, $value, 8)."\n".
[ "M", "MB" ], [ "G", "GB" ] ]);
}
# get_table_index_stats(db)
# Retrieves index stats for all tables in the given database
sub get_table_index_stats
{
my ($db) = @_;
my $table_list = join(", ", map { "'$_'" } &list_tables($db));
my $sql_query = "
SELECT
TABLE_SCHEMA,
TABLE_NAME,
INDEX_NAME,
NON_UNIQUE,
SEQ_IN_INDEX,
COLUMN_NAME,
COLLATION,
CARDINALITY,
SUB_PART,
PACKED,
NULLABLE,
INDEX_TYPE,
COMMENT,
INDEX_COMMENT
FROM
INFORMATION_SCHEMA.STATISTICS
WHERE
TABLE_SCHEMA = '$db' AND TABLE_NAME IN ($table_list);
";
my $rs = &execute_sql_safe($db, $sql_query);
return $rs;
}
# list_indexes(db)
# Returns the names of all indexes in some database
sub list_indexes
@ -1352,6 +1383,33 @@ foreach my $table (&list_tables($db)) {
return $info;
}
# parse_index_structure(&db_stats, db, indexname)
# Returns information on an index based on the database stats hash
sub parse_index_structure
{
my ($db_stats, $db, $index) = @_;
my ($r, $info);
foreach my $table (&list_tables($db)) {
my $s = { %$db_stats };
$s->{'data'} = [grep { $_->[1] eq $table } @{$s->{'data'}}];
my (%tp, $i);
for($i=0; $i<@{$s->{'titles'}}; $i++) {
$tp{lc($s->{'titles'}->[$i])} = $i;
}
foreach $r (@{$s->{'data'}}) {
if ($r->[$tp{'index_name'}] eq $index) {
# Found some info
$info->{'table'} = $r->[$tp{'table_name'}];
$info->{'name'} = $index;
$info->{'type'} = lc($r->[$tp{'index_type'}]) ||
lc($r->[$tp{'comment'}]);
push(@{$info->{'cols'}}, $r->[$tp{'column_name'}]);
}
}
}
return $info;
}
# list_views(db)
# Returns the names of all views in some database
sub list_views