From b03f1b766fcff07eebe6a8752724a3e71d8412ab Mon Sep 17 00:00:00 2001 From: Ilia Ross Date: Fri, 26 Jul 2024 19:56:45 +0300 Subject: [PATCH] Fix to optimize getting table index stats for large tables --- mysql/edit_dbase.cgi | 4 ++- mysql/mysql-lib.pl | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/mysql/edit_dbase.cgi b/mysql/edit_dbase.cgi index 634871a90..ae0d07508 100755 --- a/mysql/edit_dbase.cgi +++ b/mysql/edit_dbase.cgi @@ -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, "$text{'dbase_index'}"); push(@fields, scalar(@{$str->{'cols'}})); } diff --git a/mysql/mysql-lib.pl b/mysql/mysql-lib.pl index d3ce973ca..a7bae588f 100755 --- a/mysql/mysql-lib.pl +++ b/mysql/mysql-lib.pl @@ -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