Mysql execution plan changes due to an increase in data volume

Source: Internet
Author: User

As the data volume increases, the mysql execution plan changes. After receiving a call from the O & M personnel, the number of connections to the mysql server is full. log on to the server and check that the number is full. Well, first increase the number of connections to 2500 to provide external services temporarily. The connection continues to rise and reaches 2500 again. It is found that a large number of queries have taken nearly 1200 seconds, and a large number of persistent connections have accumulated, resulting in the increase in the number of connections. It seems that the problem is still SQL. In these persistent connections, such SQL statements are found

SELECT product_id,gift_id,gift_original_price,gift_count, FROM promo_xxx WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;mysql> explain  SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift  WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;+----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table           | type | possible_keys | key  | key_len | ref  | rows   | Extra       |+----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+|  1 | SIMPLE      | promo_gift_list | ALL  | id_promo_gift | NULL | NULL    | NULL | 249188 | Using where | +----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+1 row in set (0.04 sec)mysql> show index from promo_gift;+-----------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table           | Non_unique | Key_name        | Seq_in_index | Column_name     | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |+-----------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| promo_gift_list |          0 | PRIMARY         |            1 | id              | A         |      261184 |     NULL | NULL   |      | BTREE      |         |               | | promo_gift_list |          0 | id_promo_gift   |            1 | promotion_id    | A         |        1140 |     NULL | NULL   | YES  | BTREE      |         |               |  | promo_gift_list |          0 | id_promo_gift   |            4 | product_id      | A         |      261184 |     NULL | NULL   | YES  | BTREE      |         |               | 

 

Why didn't I go through the full table scan with the promotion_id index? In addition, the previously created indexes are well performed. How can this problem occur today? This is a problem. You can use last_query_cost to check SQL consumption.
mysql>SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift  WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1; mysql>show status like 'last_query_cost';+-----------------+--------------+| Variable_name   | Value        |+-----------------+--------------+| Last_query_cost | 52626.599000 | +-----------------+--------------+1 row in set (0.00 sec)

 

If we do not leave the index, we will use the index forcibly.
mysql> explain SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift force index(id_promo_gift) WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;         +----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+| id | select_type | table           | type  | possible_keys | key           | key_len | ref  | rows   | Extra       |+----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+|  1 | SIMPLE      | promo_gift_list | range | id_promo_gift | id_promo_gift | 5       | NULL | 124594 | Using where | +----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+1 row in set (0.02 sec)

 

Well, what about SQL consumption when I add an index?
mysql> SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift force index(id_promo_gift) WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;         +------------+----------+---------------------+------------+| product_id | gift_id  | gift_original_price | gift_count |+------------+----------+---------------------+------------+|   22569455 | 23230046 |              147.00 |          1 | +------------+----------+---------------------+------------+1 row in set (0.40 sec)mysql> show status like 'last_query_cost';+-----------------+---------------+| Variable_name   | Value         |+-----------------+---------------+| Last_query_cost | 174432.609000 | +-----------------+---------------+1 row in set (0.00 sec)

 

We found that if this index is used, the SQL consumption is 174432.609000> 52626.599000. The mysql optimizer considers that the id_promo_gift index is used, and the SQL consumption is very large. This is why mysql does not use this index for execution. Later, the developer said that the table added more than 0.11 million data last night. Well, the data volume increased and the mysql execution plan changed. Well, add an index to the separate product_id column.
mysql> alter table promo_gift_list add index  product_id(product_id);Query OK, 0 rows affected (6.45 sec)Records: 0  Duplicates: 0  Warnings: 0mysql> explain  SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift_list  WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1 AND IFNULL(is_delete,0)!=1;+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+| id | select_type | table           | type | possible_keys            | key        | key_len | ref   | rows | Extra       |+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+|  1 | SIMPLE      | promo_gift_list | ref  | id_promo_gift,product_id | product_id | 5       | const |    2 | Using where |+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+1 row in set (0.00 sec)

 

The Newly Added Index product_id is used.
mysql>  SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift_list  WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1 AND IFNULL(is_delete,0)!=1;         +------------+----------+---------------------+------------+| product_id | gift_id  | gift_original_price | gift_count |+------------+----------+---------------------+------------+|   22569455 | 23230046 |              147.00 |          1 | +------------+----------+---------------------+------------+1 row in set (0.00 sec)mysql> show status like 'last_query_cost';+-----------------+----------+| Variable_name   | Value    |+-----------------+----------+| Last_query_cost | 2.399000 | +-----------------+----------+1 row in set (0.01 sec)

 

SQL consumption reduced to 2.399000, OK, problem solving. The number of connections quickly dropped from more than 1000 to less than 100. The increase in data volume leads to a change in the mysql execution plan. How is the mysql cost calculated? Cost = io_cost + cpu_cost is located at the upper layer of mysql. The overhead for processing returned records is included in the io_cost storage engine layer, and there is no IO overhead for reading. Last_query_cost is the most direct way to record SQL cost. Check last_query_cost To preliminarily judge the SQL cost and understand the basis for executing the mysql optimizer.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.