`
丁林.tb
  • 浏览: 788317 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

A new parameter to control updating statistics strategy

阅读更多

       If a table contains several indexes and a select query does not have a “force index” hint clause, the MySQL optimizer take charge of determining which index to use. In some cases, we find that MySQL optimizer does not select the best index.

Here we discuss a strategy to deal with the problem, using a new parameter.

 

1、table and index statistics

The statistics contains the number of different key values in a given index, which affects the decision of index selection.

       In a big table, it is not workable that scans all the rows and counts the accurate statistics. So InnoDB pick up some example rows to estimate the result. The variable “innodb_stats_sample_pages “is used to define the number of example rows. Its default value is 8.

       There should be a balance consideration about this variable. Because the function “dict_update_statistics”, which is used to update a table’s statistics, is automatically called at various times. The bigger the innodb_stats_sample_pages is, the more accurate result comes, but it may lead to excessive I/O and CPU.

 

2、When the dict_update_statistics called?

There are some scenarios that dict_update_statistics will be called.

a)       Statements like “show status”

Such as “show index from table-name” and “show status like ‘’”.  There is a variable named “innodb_stats_on_metadata” to control whether run dict_update_statistics in such queries. Default value is ON.

b)       Table monitor

When a table named “innodb_table_monitor”(InnoDB table) is created, table monitor will be run every minute. “dict_update_statistics” is called here.

c)        Analyze table table-name

d)       Dynamically during insert/update operation.

This is why the innodb_stats_sample_pages cannot be set too big. There is a counter to record the times of modifying indexed column of this table from last dict_update_statistics. When the counter is up to 2000000000 or 1/16 of the table row number, dict_update_statistics is called.

 

3、Force re-calculate statistics using analyze table

Let’s look into the next steps:

Set innodb_stats_sample_pages = BIGNUM;

Analyze table table-name;

Set innodb_stats_sample_pages = 8;

 

Obviously this does not make sense, for the reason of d) in last section.

 

4、Strategy for certain requirement

But let’s think about this case, when there are lots of rows in a table, and the row number will keep relatively stable in a period.

We run the analyze table command, and test the queries that will run upon this table, check that the index selection working well.

Since the dynamically re-calculating may get wrong statistics and then leads to wrong index-selection, we plan to disable the mechanism, using a variable that can be update by command “set global”.

The variable can be named “innodb_stats_dynamically”, ON as default.

So when we think the data number is big enough and will be relatively stable in a period afterward, the sample commands can be as follow:

 

Set innodb_stats_dynamically = off;

Set innodb_stats_sample_pages = BIGNUM;

Analyze table table-name;

Set innodb_stats_sample_pages = 8; (optional)

 

        

  • 大小: 45 KB
1
0
分享到:
评论
1 楼 whitesock 2012-02-08  
以前线上也遇到过这样的问题,没有什么太好的办法。关掉innodb_stats_on_metadata,然后定期对比一下show index from的输出。

相关推荐

Global site tag (gtag.js) - Google Analytics