SQL Optimization · Classic Case · Index Chapter

Source: Internet
Author: User

Introduction

In the work of these years, due to the SQL problem caused by a number of database failures, the following six years of work encountered in the SQL problem summary collation, restore the original, give the analysis of the problem ideas and solve the problem of the method, to help users in the process of using the database can take a few detours. A total of four parts: index, SQL rewrite, parameter optimization, optimizer section Four, today will introduce the first part: Index chapter.

Index problems are the most frequently occurring in SQL problems, and common indexing problems include: No indexes, implicit conversions. When the database has access to the table of SQL No index results in a full table scan, if the data volume of the table is large, scan a large amount of data, application requests become slow to occupy the database connection, the connection accumulation will quickly reach the maximum number of connections to the database settings, new application requests will be rejected to cause the failure. Implicit conversions are when an incoming value in an SQL query condition is inconsistent with the data definition of the corresponding field, causing the index to be unusable. Common Hermit conversions The table structure of a field is defined as a character type, but the SQL pass-in value is a number, or the field definition collation is case-sensitive, and in a multi-table associated scenario, its table's associated field case sensitivity definitions vary. Implicit conversions can cause the index to become unusable, resulting in the number of slow SQL stacked database connections running full.

No index case:

Table structure

CREATE TABLE `user` (……mo bigint NOT NULL DEFAULT ‘‘ ,KEY ind_mo (mo) ……) ENGINE=InnoDB;SELECT uid FROM `user` WHERE mo=13772556391 LIMIT 0,1

Execution plan

mysql> explain  SELECT uid FROM `user` WHERE mo=13772556391 LIMIT 0,1;           id: 1  select_type: SIMPLE        table: user         type: ALLpossible_keys: NULL          key: NULL         rows: 707250         Extra: Using where

From the above SQL to see the execution plan all, represents the SQL execution plan is a full table scan, each execution needs to scan 707250 rows of data, which is very consumption performance, how to optimize? Add an index.
Verifying the filtering of MO fields

mysql> select count(*) from user where mo=13772556391;|   0    |

You can see that the filtering of the Mo field is very high, and further verification can be done through the select count (*) as all_count,count (distinct mo) as distinct_cnt from user, through-contrast All_ The values of count and distinct_cnt are compared, and it is very effective to add indexes on the Mo field if the all_cnt and distinct_cnt are very different.

Add index

mysql> alter table user add index ind_mo(mo);mysql>SELECT uid FROM `user` WHERE mo=13772556391 LIMIT 0,1;Empty set (0.05 sec)

Execution plan

mysql> explain  SELECT uid FROM `user` WHERE mo=13772556391 LIMIT 0,1\G;*************************** 1. row ***************************               id: 1      select_type: SIMPLE            table: user             type: index    possible_keys: ind_mo              key: ind_mo             rows: 1            Extra: Using where; Using index
Implicit conversion case One

Table structure

  CREATE TABLE `user` (  ……  mo char(11) NOT NULL DEFAULT ‘‘ ,  KEY ind_mo (mo)  ……  ) ENGINE=InnoDB;

Execution plan

mysql> explain extended select uid from`user` where mo=13772556391 limit 0,1;mysql> show warnings;Warning1:Cannot use  index ‘ind_mo‘ due to type or collation conversion on field ‘mo‘                                                                        Note:select `user`.`uid` AS `uid` from `user` where (`user`.`mo` = 13772556391) limit 0,1

How to Solve

mysql> explain   SELECT uid FROM `user` WHERE mo=‘13772556391‘ LIMIT 0,1\G;*************************** 1. row ***************************              id: 1     select_type: SIMPLE           table: user            type: ref   possible_keys: ind_mo             key: ind_mo            rows: 1           Extra: Using where; Using index

In the above case, because the table structure defines the MO field after the string data type, and the application passed in is a number, resulting in implicit conversions, the index is not available, so there are two scenarios:
First, change the table structure MO to the numeric data type.
Second, modify the app to change the character type passed in to the data type.

Implicit conversion case Two

Table structure

CREATE TABLE `test_date` (     `id` int(11) DEFAULT NULL,     `gmt_create` varchar(100) DEFAULT NULL,     KEY `ind_gmt_create` (`gmt_create`)) ENGINE=InnoDB AUTO_INCREMENT=524272;

5.5 Version Execution plan

mysql> explain  select * from test_date where gmt_create BETWEEN DATE_ADD(NOW(), INTERVAL - 1 MINUTE) AND   DATE_ADD(NOW(), INTERVAL 15 MINUTE) ;+----+-------------+-----------+-------+----------------+----------------+---------+------+------+-------------+| id | select_type | table | type | possible_keys  | key | key_len | ref  | rows | Extra       |+----+-------------+-----------+-------+----------------+----------------+---------+------+------+-------------+|1|SIMPLE| test_date |range| ind_gmt_create|ind_gmt_create|303| NULL | 1 | Using where |

5.6 Version Execution Plan

mysql> explain select * from test_date where gmt_create BETWEEN DATE_ADD(NOW(), INTERVAL - 1 MINUTE) AND   DATE_ADD(NOW(), INTERVAL 15 MINUTE) ; +----+-------------+-----------+------+----------------+------+---------+------+---------+-------------+| id | select_type | table | type | possible_keys  | key  | key_len | ref | rows | Extra|+----+-------------+-----------+------+----------------+------+---------+------+---------+-------------+| 1 | SIMPLE| test_date | ALL | ind_gmt_create | NULL | NULL | NULL | 2849555 | Using where |+----+-------------+-----------+------+----------------+------+---------+------+---------+-------------+|Warning|Cannot use range access on index ‘ind_gmt_create‘ due to type on field ‘gmt_create‘   

The above case is an implicit conversion that occurs after the user has upgraded to version 5.5 to 5.6, resulting in a database CPU pressure of 100%, so we must use the time-type data type when defining the Time field.

Implicit conversion case Three

Table structure

  CREATE TABLE `t1` (  `c1` varchar(100) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,  `c2` varchar(100) DEFAULT NULL,  KEY `ind_c1` (`c1`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `t2` (  `c1` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,  `c2` varchar(100) DEFAULT NULL,  

Execution plan

mysql> explain     select t1.* from  t2 left  join  t1 on t1.c1=t2.c1 where t2.c2=‘b‘;+----+-------------+-------+------+---------------+--------+---------+-------+--------+-------------+| id | select_type | table | type | possible_keys |key| key_len | ref   | rows   | Extra    |+----+-------------+-------+------+---------------+--------+---------+-------+--------+-------------+| 1 | SIMPLE | t2 | ref  | ind_c2 | ind_c2 | 303     | const |    258 | Using where ||1  |SIMPLE |t1  |ALL   | NULL   | NULL   | NULL    | NULL  | 402250 |    |

Modify COLLATE

mysql> alter table t1 modify column c1 varchar(100) COLLATE utf8_bin ;                Query OK, 401920 rows affected (2.79 sec)Records: 401920  Duplicates: 0  Warnings: 0

Execution plan

mysql> explain   select t1.* from  t2 left  join  t1 on t1.c1=t2.c1 where t2.c2=‘b‘;+----+-------------+-------+------+---------------+--------+---------+------------+-------+-------------+| id | select_type | table | type | possible_keys | key  | key_len | ref | rows  | Extra       |+----+-------------+-------+------+---------------+--------+---------+------------+-------+-------------+|  1 | SIMPLE| t2| ref | ind_c2| ind_c2 | 303     | const      |   258 | Using where ||  1 |SIMPLE| t1|ref| ind_c1  | ind_c1 | 303     | test.t2.c1 | 33527 |             |+----+-------------+-------+------+---------------+--------+---------+------------+-------+-------------+

You can see that the collate of the field has been modified to use the index, so be aware that the definition of the Collate property of the table fields is consistent.

Common pitfalls of two indexes
    • Myth One: Establish a single-column index for each field of the query condition, for example, the query condition is: a=? and b=? and c=?.
      An index of 3 single-column query criteria was created on the table ind_a (A), Ind_b (B), Ind_c (C), should be created with the appropriate single-column index or combined index based on the filtering of the condition.

    • Myth Two: Set up a composite index on all fields of the query, for example, the query condition is select A,b,c,d,e,f from T where g=?.
      Ind_a_b_c_d_e_f_g (A,B,C,D,E,F,G) was created on the table.

Index Best Practices
      • When using the index, we can view the SQL execution plan by explain+extended, determine whether the index is used, and an implicit conversion has occurred.
      • Because the common implicit conversions are caused by improper field data types and collation definitions, we want to avoid the definition of database fields in the design development phase and avoid implicit conversions.
      • Since MySQL does not support function indexing, you should avoid adding functions, such as Date (Gmt_create), to the query criteria at development time.
      • All on-line SQL has to undergo rigorous audits to create the right index.

SQL Optimization · Classic Case · Index Chapter

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.