MySQL slow query analysis case

   With the growth of business volume, the operation colleagues reported that a report page is getting slower and slower, and screened the sub-queries one by one from the corresponding report statements to find the slowest statement as follows:

   It can be seen that a subset of the full table has scanned more than 3 million rows of data. Extract it to explain separately and locate the problem statement:

 

SELECT t1.statDate, t1.tips
      FROM passport_4366_test t1
      WHERE t1.statDate>='2016-05-01'
        AND t1.statDate<='2016-05-05'
      GROUP BY t1.statDate, t1.tips;

   Check the table structure and find that an index is clearly established on the statDate of the table. It is reasonable to say that the type should be range. How can it be all?

   Try removing the group by statement:


   Still a full table scan. Remove a field and try again:


   The amount of data to be scanned becomes 1/5, and the type becomes range. So what causes the MySQL query executor to give up using the index to perform a full table scan directly? Go ask Google and find the following articles that might help:



   Looking back, this table field is of type date. Is it because the table generates too much data on the same day, which reduces the index discrimination and causes the query executor to give up the treatment? So, would it be better to change this field to datetime type? OK, let's try it out. 

create table passport_4366_test like passport_4366;
insert into passport_4366_test select * from passport_4366 where statDate>='2016-04-01' AND statDate<='2016-05-06';
alter table passport_4366_test add index dt_idx(updateTime);
alter table passport_4366_test drop index statDate;

   Then explain to see:

   Really stubborn MySQL, had to force index:


   Finally obediently. There is another solution that comes to mind, that is to create a joint index:

alter table passport_4366_test add index statDate_tips_idx(statDate, tips);

   Let's take a look at the result of explain:

   Works great, the rows column is even better than the force index (probably because of Index Condition Pushdown Optimization). Expand the time range and execute the statement directly to compare the execution time:


   The result is that the joint index wins.

   Finally, to summarize:

1. When creating an index, try to select a column with a large degree of discrimination;

2. Consider establishing a joint index under appropriate conditions. For example, the advantages of joint index in this example are obvious;

3. When writing SQL, you need to explain more, mainly depending on the type and rows. Generally speaking, the execution efficiency is const > eq_ref > ref > range > all, and the fewer the rows value, the better.

   Reference article:

http://blog.csdn.net/mchdba/article/details/9190771

https://www.percona.com/blog/2014/01/03/multiple-column-index-vs-multiple-indexes-with-mysql-56/

http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html

http://tech.meituan.com/mysql-index.html

http://dba.stackexchange.com/questions/19400/why-does-mysql-only-sometimes-use-my-index-for-a-range-query

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326918893&siteId=291194637