MySQL - WHERE優化篇

平常開發中,編寫SQL語句都避免不了使用到 WHERE關鍵字作條件過濾,細心的朋友就會發現,WHERE的不一樣表現形式會對數據庫性能形成必定影響,本章主要針對 WHERE優化策略進行討論....

<!-- more -->mysql

優化要素

  • 想要讓SELECT .... WHERE ...變快,第一就是檢查一下是否能夠增長索引。在WHERE子句中建立索引,能夠加快求值、過濾、和最終檢索結果的速度。爲避免浪費磁盤空間,能夠經過建立聯合索引來加速多個相關查詢。
  • 儘可能減小全表掃描的查詢,尤爲對於大表更要杜絕全表掃描。
  • 減小函數使用(尤爲是耗時的函數)。一個函數可能在結果集中每行都被調用一次或者在一個表裏面每一行都被調用一次,這樣作效率是很是低的。
  • 掌握不一樣存儲引擎的優化方案,合理的運用索引技術。
  • 優化InnoDB事務。(對於統計型的數據,開啓只讀事務)
  • 避免將查詢轉換成比較難以理解的方式,以避免MySQL沒法進行優化
  • 熟練掌握EXPLAIN計劃
  • 調整MySQL用於緩存數據的內存大小
  • 減小鎖表的狀況

內置優化

在作JAVA開發中,經過指令重拍會對代碼作必定程度的優化,在數據庫中MYSQL優化器也作了一系列相關優化工做,下面要介紹的就是數據庫作的內置優化sql

方案一: 刪除沒必要要的括號
((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)
方案二: 常量摺疊/常量疊算
(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
更多: 其餘方案
  • 索引使用常量表達式時只計算一次,因此儘量使用產生const的查詢方式(主鍵查詢)
  • 對於MyISAM和MEMORY表來講,在一個單獨的表上,若是使用COUNT(*)可是沒有WHERE子句的話,那麼就會直接從表的信息裏面檢索數據。當在一個表中用NOT NULL表達式的時候也是這麼作的。
  • 發現無效的常量表達式。MySQL會及時發現無效SELECT語句,而後不返回數據。
  • WHERE查詢中發現未使用GROUP BY或者聚合函數(好比COUNT(),MIN()等),那麼HAVING會與WHERE合併。
  • 多表查詢中,MYSQL會對錶進行評估從而構造出更簡單的查詢
  • 優先讀取常量表數據庫

    • 空表或者一個有一行的表。
    • WHERE子句在PRIMARY KEY或者UNIQUE INDEX上的表,其中索引和常量表達式做比較,並被定義爲NOT NULL緩存

      SELECT * FROM t WHERE primary_key = 1;
      SELECT * FROM t1,t2
        WHERE t1.primary_key= 1  AND t2.primary_key = t1.id;
  • 關聯查詢時,MySQL會去嘗試全部的可能性,從而發現最好的的組合方式。當ORDER BYGROUP BY子句的列都位於同一個表時,該表將會第一個被連接。
  • 若是ORDER BYGROUP BY 字段不一樣,或是除join queue中的第一個表以外其它含有ORDER BYGROUP BY的表都會爲其建立臨時表
  • 若是使用了 SQL_SMALL_RESULT 選項,那麼MySQL就會在內存中建立一個臨時表。
  • MySQL每次查詢時都會檢查是否有可用索引,除非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;
索引樹查詢(索引列是數字的狀況下)
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, ... ;

總結

最好的優化方案,跟着新版本走推陳出新,新版中不只擴展更多功能,同時會增強優化力度。雖然MySQL優化器爲咱們作了不少事情,但開發過程當中改主意還得注意。架構

說點什麼

祝各位元旦快樂,吃嘛嘛香,2018裏把全部吹的牛逼都給實現咯。函數

關注微信公衆號:battcn 後臺回覆 mysql 便可得到 《打造扛得住的MySQL數據庫架構》性能

  • 我的QQ:1837307557
  • battcn開源羣(適合新手):391619659
相關文章
相關標籤/搜索