ANALYZE
This statement updates the statistics that TiDB builds on tables and indexes. It is recommended to run ANALYZE
after performing a large batch update or import of records, or when you notice that query execution plans are sub-optimal.
TiDB will also automatically update its statistics over time as it discovers that they are inconsistent with its own estimates.
Currently, TiDB collects statistical information as a full collection by using the ANALYZE TABLE
statement. For more information, see Introduction to statistics.
Synopsis
- AnalyzeTableStmt
- AnalyzeOptionListOpt
- AnalyzeOptionList
- AnalyzeOption
- AnalyzeColumnOption
- TableNameList
- TableName
- ColumnNameList
- IndexNameList
- PartitionNameList
AnalyzeTableStmt ::=
'ANALYZE' ( 'TABLE' ( TableNameList ( 'ALL COLUMNS' | 'PREDICATE COLUMNS' ) | TableName ( 'INDEX' IndexNameList? | AnalyzeColumnOption | 'PARTITION' PartitionNameList ( 'INDEX' IndexNameList? | AnalyzeColumnOption )? )? ) ) AnalyzeOptionListOpt
AnalyzeOptionListOpt ::=
( WITH AnalyzeOptionList )?
AnalyzeOptionList ::=
AnalyzeOption ( ',' AnalyzeOption )*
AnalyzeOption ::=
( NUM ( 'BUCKETS' | 'TOPN' | ( 'CMSKETCH' ( 'DEPTH' | 'WIDTH' ) ) | 'SAMPLES' ) ) | ( FLOATNUM 'SAMPLERATE' )
AnalyzeColumnOption ::=
( 'ALL COLUMNS' | 'PREDICATE COLUMNS' | 'COLUMNS' ColumnNameList )
TableNameList ::=
TableName (',' TableName)*
TableName ::=
Identifier ( '.' Identifier )?
ColumnNameList ::=
Identifier ( ',' Identifier )*
IndexNameList ::=
Identifier ( ',' Identifier )*
PartitionNameList ::=
Identifier ( ',' Identifier )*
Examples
mysql> CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, c1 INT NOT NULL);
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO t1 (c1) VALUES (1),(2),(3),(4),(5);
Query OK, 5 rows affected (0.03 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t1 ADD INDEX (c1);
Query OK, 0 rows affected (0.30 sec)
mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3;
+------------------------+---------+-----------+------------------------+---------------------------------------------+
| id | estRows | task | access object | operator info |
+------------------------+---------+-----------+------------------------+---------------------------------------------+
| IndexReader_6 | 10.00 | root | | index:IndexRangeScan_5 |
| └─IndexRangeScan_5 | 10.00 | cop[tikv] | table:t1, index:c1(c1) | range:[3,3], keep order:false, stats:pseudo |
+------------------------+---------+-----------+------------------------+---------------------------------------------+
2 rows in set (0.00 sec)
The status of the current statistics is pseudo
, which means the statistics is inaccurate.
mysql> ANALYZE TABLE t1;
Query OK, 0 rows affected (0.13 sec)
mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3;
+------------------------+---------+-----------+------------------------+-------------------------------+
| id | estRows | task | access object | operator info |
+------------------------+---------+-----------+------------------------+-------------------------------+
| IndexReader_6 | 1.00 | root | | index:IndexRangeScan_5 |
| └─IndexRangeScan_5 | 1.00 | cop[tikv] | table:t1, index:c1(c1) | range:[3,3], keep order:false |
+------------------------+---------+-----------+------------------------+-------------------------------+
2 rows in set (0.00 sec)
The statistics is now correctly updated and loaded.
MySQL compatibility
TiDB differs from MySQL in both the statistics it collects and how it makes use of statistics during query execution. While this statement is syntactically similar to MySQL, the following differences apply:
- TiDB might not include very recently committed changes when running
ANALYZE TABLE
. After a batch update of rows, you might need tosleep(1)
before executingANALYZE TABLE
in order for the statistics update to reflect these changes. See #16570. ANALYZE TABLE
takes significantly longer to execute in TiDB than MySQL.