Optimize the select statement
- In order to make the slow
SELECT ... WHERE
query faster, the first thing to check is whether you can add an index. To avoid wasting disk space, construct a composite index . - Adjust the function call , the function call is many times reduced from a first, greatly improving efficiency.
- Regular use of
ANALYZE TABLE
the table statistical information up to date, provide the information needed to construct effective implementation of the plan for the optimizer. - Read the
EXPLAIN
plan and adjust the index. - Adjusting MySQL cache memory area for the size and properties.
- Avoid query performance problems caused by the lock.
1. WHERE clause optimization
-
Remove unnecessary parentheses.
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
-
Constant folding.
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
-
Constant condition is removed.
(b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=7 AND 5=6) -> b=5 OR b=6
-
Index is calculated using a constant expression only once.
-
Directly from MyISAM and MEMORY look-up table COUNT on a single table with no WHERE (*).
-
Invalid constant expressions.
SELECT * FROM t WHERE a<0 AND a>1; ︶︵︶
-
If no or GROUP BY aggregate functions (e.g.
COUNT()
,MIN()
), etc.) will be incorporated into the HAVING clause WHERE clause.SELECT * FROM t WHERE a=1 HAVING b>1; -> SELECT * FROM t WHERE a=1 AND b>1;
-
For each of the coupling table, construct a simpler WHERE WHERE for fast evaluation of the table, and as soon as the line is skipped. (Complex WHERE filter delay time for each line of data)
-
In all the tables in the query, often read priority scale. Constant table can be any of the following
-
Empty table or a table with one row;
-
For use with a table or PRIMARY KEY UNIQUE WHERE clause on the index, all of which are part of the index is compared to constant expressions, and is defined as NOT NULL;
All of the following tables are used as constant tables:
SELECT * FROM t WHERE primary_key=1; SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
-
-
If
ORDER BY
andGROUP BY
all columns clause from the same table, the table takes precedence when connected. -
ORDER BY
OrGROUP BY
comprising a list other than the first connection table queue, it will create a temporary table (for a sorted connection data set sorted automatically deleted). -
When all the numbers are listed in the index column, MySQL can even read rows from the index without query data files.
-
Before the output of each row,
HAVING
the row is skipped not match those of the clause. (HAVING doing cropping of the result set, does not reduce the number of scan lines)
Quick query example:
SELECT COUNT(*) FROM tbl_name;
SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
SELECT MAX(key_part2) FROM tbl_name WHERE key_part1=constant;
SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;
Assuming that the index column is a number, MySQL uses only the index tree to resolve the following query:
SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
SELECT COUNT(*) FROM tbl_name
WHERE key_part1=val1 AND key_part2=val2;
SELECT key_part2 FROM tbl_name GROUP BY key_part1;
The following query uses the index to retrieve the rows in sorted order without a separate sorting traversal:
SELECT ... FROM tbl_name
ORDER BY key_part1,key_part2,... ;
SELECT ... FROM tbl_name
ORDER BY key_part1 DESC, key_part2 DESC, ... ;
2. Range Optimizer
For BTREE and HASH index, when =, <=>, IN, IS NULL or IS NOT NULL operator,
Comparison with the relationship between key elements of constant values corresponding to a range of conditions.
HASH
Use index =, <=>, IN (), IS NULL, or IS NOT NULL operator equality comparison quickly.BTREE
Index using>, <,> =, < =, BETWEEN,! =, Or <>, LIKE 'pattern' (where 'pattern' does not start with a wildcard) operator, comparing the relationship between the key elements and a constant value corresponding to a range of conditions .
Range from attempts to optimize WHERE
clause for each possible index extraction range condition . During the extraction, remove the conditions can not be used to build a range of conditions, the combined condition occurs overlapping ranges, and removes the empty range condition occurs . Refer to the optimization process range access method of the single part of the index .
More than 2.1 compared values equidistant range optimization
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2));
INSERT INTO t1 VALUES
(1,1), (1,2), (1,3), (1,4), (1,5),
(2,1), (2,2), (2,3), (2,4), (2,5);
INSERT INTO t1 SELECT f1, f2 + 5 FROM t1;
INSERT INTO t1 SELECT f1, f2 + 10 FROM t1;
INSERT INTO t1 SELECT f1, f2 + 20 FROM t1;
INSERT INTO t1 SELECT f1, f2 + 40 FROM t1;
ANALYZE TABLE t1;
EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40;
MySQL index scan may be selected for all rows, then in accordance with clause f2 > 40
conditions WHERE
to produce a final result set. More effective than the full scanning range index scan, but can not be used in this case, since there is no conditions are listed in the first index f1
on. However, starting from MySQL 8.0.13, the optimizer may use a method called "skip scan" of the primary scanning range of the scanning range is divided into a plurality of times, and then merge the results returned multiple scans.
Run algorithm is as follows:
- Gets the index of a different value (
f1 = 1
). - According to a first configuration and a second index range (
f1 = 1 AND f2 > 40
). - Perform a range scan.
- Gets the index at a different value (
f1 = 2
). - According to a first configuration and a second index range (
f1 = 2 AND f2 > 40
). - Perform a range scan.
Use this policy to reduce the number of access lines, because MySQL will skip does not meet the construction line of each range. This "skip scan" access method applies to the following situations:
- Table T has at least one composite index, which index is the form ([A_1, ..., A_
k
,] B_1, ..., B_m
, C [, D_1, ..., D_n
]). A and D key part may be empty, but B and C must be non-empty. . - The query uses only one table.
- Query does not use
GROUP BY
orDISTINCT
. - The query references only column in the index.
- Prefix A_1, ..., A_ *
k
* must be equal predicate, and they must be constant. This includesIN()
. - The query must be a joint inquiry. That is,
AND
theOR
condition. - There must be a range condition C .
- Allows the filter conditions in the D field, but must be used with the range condition C.
For the jump range scanning features SQL, use EXPLAIN to see its execution plan, you can see:
- Extra execution plan output in the column there: Using index for skip scan
- In possible_keys column will display the execution plan output can be used to index
Range constructor expression of 2.2 line optimization
Optimizer can range scan access method used in the form of a query:
SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));
In order to optimize the use scanning range, the query must meet the following criteria:
-
Using only the IN () predicate, without using NOT IN ().
-
In the IN () predicate on the left side, the line contains only the configuration of a column reference.
-
In the IN () predicate on the right side, the line contains only the configuration of run-time constant.
-
On the right side predicate IN (), a plurality of row constructors.