The road to msyql optimization ------ adjust the SQL statement -- (2.2) optimize the select statement

1. Optimize the where statement
Although it is the where condition of the optimized select statement; it also applies to update and delete. Also avoid optimizations that speed up arithmetic operations at the expense of readability, because mysql does such optimizations; mysql performs the following optimizations:
Remove unnecessary brackets
((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: an optimization technique used in modern compilers
(a<b AND b=c) AND a=5
b>5 AND b=c AND a=5
Remove constant condition (required for constant folding)
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
B=5 OR B=6
Constant expressions used by index are evaluated only once.
In a single table without where condition, COUNT(*) is directly obtained from the table information for MyISAM and MEMORY tables. The same is true for single tables with NOT NULL expressions.
Early detection of invalid constant expressions. MySQL quickly detects certain SELECT statements that are impossible and return no rows.
If you do not use GROUP BY or aggregate functions ( COUNT() MIN() , etc.), HAVING will be merged by WHERE.
对于连接中的每个表,WHERE构造一个更简单 的表达式以快速 对标WHERE评估,并尽快跳过行。
在查询中的所有常量表要先于其他表被读取。常数表是以下任何一项:
1)空表或只有一行的表
2)使用主键或唯一索引查询的表,所有索引部分与常量表达式比较,且被定义为NOT NULL。
常量表
SELECT * FROM t WHERE primary_key = 1 ;
SELECT * FROM t1 , t2
WHERE t1 . primary_key = 1 AND t2 . primary_key = t1 . id ;
通过尝试所有可能性来找到加入表格的最佳联合组合。如果 ORDER BY和GROUP BY子句的所有列来自同一个表,那么在连接时首先选择该表。
如果有一个ORDER BY子句和一个不同的GROUP BY子句,或者如果 ORDER BY或GROUP BY 包含表的列不是连接队列表的列,则会创建一个临时表。
如果你使用SQL_SMALL_RESULT 修饰符,MySQL使用内存中的临时表
除非优化器认为使用索引比全表扫描更高效,查询才会使用索引进行查询。曾经,是否超过表格的30%作为是否使用索还是使用全表扫描,但是固定百分比不再决定使用索引或全表扫描。优化器现在更加复杂,并基于其他因素,如表大小,行数和I / O块大小。
在某些情况下,MySQL可以从索引中读取行,而无需咨询数据文件。如果索引中使用的所有列都是数字,则仅使用索引树来解析查询。
在输出每行之前,不匹配 HAVING子句的内容将被跳过。
查询速度很快的例子:

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;

假设索引列是数字的,MySQL仅使用索引树来解析以下查询:

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;

以下查询使用索引来按照排序顺序检索行,而无需单独的排序传递:

SELECT ... FROM tbl_name
ORDER BY key_part1 , key_part2 ,... ;

SELECT ... FROM tbl_name
ORDER BY key_part1 DESC, key_part2 DESC, ... ;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324769942&siteId=291194637