Skip to content

Commit 5237292

Browse files
shlomi-noachdbussink
authored andcommitted
New variable and behavior: fast_analyze_table for, well, faster ANALYZE TABLE
Introducing a new global/session variable: fast_analyze_table, a boolean that defaults false. When the value is true (or 1), then an ANALYZE TABLE only analyzes and persists stats for the clustering index (normally the PRIMARY KEY) and skips the secondary keys. The purpose of this change is to support faster ANALYZE TABLE operations, where all we want is really to get an updated estimation of the number of rows in the table. That information is extracted from the clustering index, not from the secondary keys, and thus they can be skipped. Signed-off-by: Dirkjan Bussink <[email protected]>
1 parent 7601d17 commit 5237292

File tree

7 files changed

+70
-3
lines changed

7 files changed

+70
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
drop table if exists t0;
2+
create table t0 (id int primary key);
3+
show global variables like 'fast_analyze_table';
4+
Variable_name Value
5+
fast_analyze_table OFF
6+
show session variables like 'fast_analyze_table';
7+
Variable_name Value
8+
fast_analyze_table OFF
9+
select @@global.fast_analyze_table;
10+
@@global.fast_analyze_table
11+
0
12+
select @@session.fast_analyze_table;
13+
@@session.fast_analyze_table
14+
0
15+
set @@fast_analyze_table=1;
16+
show global variables like 'fast_analyze_table';
17+
Variable_name Value
18+
fast_analyze_table OFF
19+
show session variables like 'fast_analyze_table';
20+
Variable_name Value
21+
fast_analyze_table ON
22+
analyze table t0;
23+
Table Op Msg_type Msg_text
24+
test.t0 analyze status OK
25+
set @@fast_analyze_table=0;
26+
drop table if exists t0;

mysql-test/t/fast_analyze_table.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# Test of fast_analyze_table variable
3+
#
4+
5+
--source include/count_sessions.inc
6+
7+
--disable_warnings
8+
drop table if exists t0;
9+
--enable_warnings
10+
11+
create table t0 (id int primary key);
12+
13+
show global variables like 'fast_analyze_table';
14+
show session variables like 'fast_analyze_table';
15+
16+
select @@global.fast_analyze_table;
17+
select @@session.fast_analyze_table;
18+
19+
set @@fast_analyze_table=1;
20+
show global variables like 'fast_analyze_table';
21+
show session variables like 'fast_analyze_table';
22+
23+
analyze table t0;
24+
set @@fast_analyze_table=0;
25+
drop table if exists t0;

sql/query_options.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,6 @@
129129
*/
130130
#define OPTION_NO_SUBQUERY_DURING_OPTIMIZATION (1ULL << 39) // intern
131131

132+
#define OPTION_FAST_ANALYZE_TABLE (1ULL << 61) // THD, user, binlog
133+
132134
#endif /* QUERY_OPTIONS_INCLUDED */

sql/sys_vars.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5601,6 +5601,12 @@ static Sys_var_bit Sys_unique_checks("unique_checks", "unique_checks",
56015601
REVERSE(OPTION_RELAXED_UNIQUE_CHECKS),
56025602
DEFAULT(true), NO_MUTEX_GUARD, IN_BINLOG);
56035603

5604+
static Sys_var_bit Sys_fast_analyze_table("fast_analyze_table", "fast_analyze_table",
5605+
HINT_UPDATEABLE SESSION_VAR(option_bits),
5606+
NO_CMD_LINE, OPTION_FAST_ANALYZE_TABLE,
5607+
DEFAULT(false), NO_MUTEX_GUARD,
5608+
IN_BINLOG);
5609+
56045610
#ifdef ENABLED_PROFILING
56055611
static Sys_var_bit Sys_profiling("profiling", "profiling",
56065612
SESSION_VAR(option_bits), NO_CMD_LINE,

storage/innobase/dict/dict0stats.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,7 +2006,7 @@ static void dict_stats_analyze_index(
20062006
will be saved on disk.
20072007
@return DB_SUCCESS or error code */
20082008
static dberr_t dict_stats_update_persistent(
2009-
dict_table_t *table) /*!< in/out: table */
2009+
dict_table_t *table, bool only_clustered_index) /*!< in/out: table */
20102010
{
20112011
dict_index_t *index;
20122012

@@ -2050,7 +2050,7 @@ static dberr_t dict_stats_update_persistent(
20502050

20512051
dict_stats_empty_index(index);
20522052

2053-
if (dict_stats_should_ignore_index(index)) {
2053+
if (only_clustered_index || dict_stats_should_ignore_index(index)) {
20542054
continue;
20552055
}
20562056

@@ -2841,6 +2841,7 @@ storage */
28412841
switch (stats_upd_option) {
28422842
dberr_t err;
28432843

2844+
case DICT_STATS_RECALC_PERSISTENT_FAST:
28442845
case DICT_STATS_RECALC_PERSISTENT:
28452846

28462847
if (srv_read_only_mode) {
@@ -2862,7 +2863,7 @@ storage */
28622863
persistent stats enabled */
28632864
ut_a(strchr(table->name.m_name, '/') != nullptr);
28642865

2865-
err = dict_stats_update_persistent(table);
2866+
err = dict_stats_update_persistent(table, stats_upd_option == DICT_STATS_RECALC_PERSISTENT_FAST);
28662867

28672868
if (err != DB_SUCCESS) {
28682869
return (err);

storage/innobase/handler/ha_innodb.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17209,6 +17209,10 @@ int ha_innobase::info_low(uint flag, bool is_analyze) {
1720917209
if (dict_stats_is_persistent_enabled(ib_table)) {
1721017210
if (is_analyze) {
1721117211
opt = DICT_STATS_RECALC_PERSISTENT;
17212+
17213+
if (m_prebuilt->trx->mysql_thd != nullptr && thd_test_options(m_prebuilt->trx->mysql_thd, OPTION_FAST_ANALYZE_TABLE)) {
17214+
opt = DICT_STATS_RECALC_PERSISTENT_FAST;
17215+
}
1721217216
} else {
1721317217
/* This is e.g. 'SHOW INDEXES', fetch
1721417218
the persistent stats from disk. */

storage/innobase/include/dict0stats.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ enum dict_stats_upd_option_t {
4646
storage, if the persistent storage is
4747
not present then emit a warning and
4848
fall back to transient stats */
49+
DICT_STATS_RECALC_PERSISTENT_FAST, /* like DICT_STATS_RECALC_PERSISTENT,
50+
but only computes statistics for the clustering index
51+
(PRIMARY KEY) */
4952
DICT_STATS_RECALC_TRANSIENT, /* (re) calculate the statistics
5053
using an imprecise quick algo
5154
without saving the results

0 commit comments

Comments
 (0)