@@ -37,6 +37,7 @@ import (
37
37
"vitess.io/vitess/go/sqltypes"
38
38
"vitess.io/vitess/go/textutil"
39
39
"vitess.io/vitess/go/vt/dbconnpool"
40
+ "vitess.io/vitess/go/vt/log"
40
41
"vitess.io/vitess/go/vt/schema"
41
42
"vitess.io/vitess/go/vt/sqlparser"
42
43
"vitess.io/vitess/go/vt/vterrors"
@@ -247,11 +248,41 @@ func (v *VRepl) readTableUniqueKeys(ctx context.Context, conn *dbconnpool.DBConn
247
248
return uniqueKeys , nil
248
249
}
249
250
251
+ // isFastAnalyzeTableSupported checks if the underlying MySQL server supports 'fast_analyze_table',
252
+ // introduced by a fork of MySQL: https://github.com/planetscale/mysql-server/commit/c8a9d93686358dabfba8f3dc5cc0621e3149fe78
253
+ // When `fast_analyze_table=1`, an `ANALYZE TABLE` command only analyzes the clustering index (normally the `PRIMARY KEY`).
254
+ // This is useful when you want to get a better estimate of the number of table rows, as fast as possible.
255
+ func (v * VRepl ) isFastAnalyzeTableSupported (ctx context.Context , conn * dbconnpool.DBConnection ) (isSupported bool , err error ) {
256
+ rs , err := conn .ExecuteFetch (sqlShowVariablesLikeFastAnalyzeTable , math .MaxInt64 , true )
257
+ if err != nil {
258
+ return false , err
259
+ }
260
+ return len (rs .Rows ) > 0 , nil
261
+ }
262
+
250
263
// executeAnalyzeTable runs an ANALYZE TABLE command
251
264
func (v * VRepl ) executeAnalyzeTable (ctx context.Context , conn * dbconnpool.DBConnection , tableName string ) error {
265
+ fastAnalyzeTableSupported , err := v .isFastAnalyzeTableSupported (ctx , conn )
266
+ if err != nil {
267
+ return err
268
+ }
269
+ if fastAnalyzeTableSupported {
270
+ // This code is only applicable when MySQL supports the 'fast_analyze_table' variable. This variable
271
+ // does not exist in vanilla MySQL.
272
+ // See https://github.com/planetscale/mysql-server/commit/c8a9d93686358dabfba8f3dc5cc0621e3149fe78
273
+ // as part of https://github.com/planetscale/mysql-server/releases/tag/8.0.34-ps1.
274
+ if _ , err := conn .ExecuteFetch (sqlEnableFastAnalyzeTable , 1 , false ); err != nil {
275
+ return err
276
+ }
277
+ log .Infof ("@@fast_analyze_table enabled" )
278
+ defer conn .ExecuteFetch (sqlDisableFastAnalyzeTable , 1 , false )
279
+ }
280
+
252
281
parsed := sqlparser .BuildParsedQuery (sqlAnalyzeTable , tableName )
253
- _ , err := conn .ExecuteFetch (parsed .Query , 1 , false )
254
- return err
282
+ if _ , err := conn .ExecuteFetch (parsed .Query , 1 , false ); err != nil {
283
+ return err
284
+ }
285
+ return nil
255
286
}
256
287
257
288
// readTableStatus reads table status information
0 commit comments