MySQL的where條件優化


where 條件優化  適合select delete update
 
1.避免無用的括號
((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)
2.常量合並
(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
3.常量條件移除
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
4.索引使用的常量表達式只計算一次
key=35+3
->key=38
5.對於MyISAM和MEMORY表,單表進行count(*)沒有where條件時,會直接從表的信息里返回結果,而不是實際執行count(*)語句,這也適合任何不為null的表達式。
select count(*) tab
select count(col1) from tab  --col1 not null
6.早期決策無效的常量表達式,MySQL很快的去決策一些select不能有行數據返回的語句。
explain select * from a where 1=2;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
7.在使用having時,如果沒有使用group by或聚合函數,having條件會合並到where條件里
explain select id from a where id=2 having id>1;
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
|  1 | SIMPLE      | a     | ref  | idx_a_id      | idx_a_id | 5       | const |    1 | Using index |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
8.對於每個進行join的表,構造更小的where條件結果集,使得where添加跳過一些行,使查詢更快速。
9.所有的常量表讀取速度要快於其他表,一個常量表是下面這樣的:
1>.一個空表或一個一行數據的表。
2>.與主鍵上的WHERE子句或惟一索引一起使用的表,其中所有索引部分都與常量表達式進行比較,並定義為NOT NULL。
下面的表使用常量表:
SELECT * FROM t WHERE primary_key=1;
SELECT * FROM t1,t2
  WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
10.試着所有的join關聯表的組合找到最好的組合。如果order by和group by條件是同一個表上,那么這個表會被第一個進行join。
11.如果有order by和group by不同的子句,或者這個order by或group by子句不在第一個表上,就會創建一個臨時表。
12.如果使用SQL_SMALL_RESULT進行修飾,MySQL會使用內存臨時表。
13.查詢每個表索引,並使用最佳索引,除非優化器認為使用表掃描更有效。曾經,根據最好的索引是否超過表的30%來使用掃描,但是固定的百分比不再決定使用索引還是使用掃描。優化器現在更加復雜,它的估計基於其他因素,如表大小、行數和I/O塊大小。
14.在一些情況,如果所有字段都在索引里,MySQL讀所有行數據都從索引讀取,不需要去數據文件讀取,只使用索引樹去解決所需查詢。
15.在輸出每一行之前,將跳過不匹配所有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, ... ;  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM