淺談關於SQL優化的思路

零、爲何要優化

  • 系統的吞吐量瓶頸每每出如今數據庫的訪問速度上
  • 隨着應用程序的運行,數據庫的中的數據會愈來愈多,處理時間會相應變慢
  • 數據是存放在磁盤上的,讀寫速度沒法和內存相比

1、觀察

MySQL優化≠SQL語句優化,理解這一點很是重要,雖然大部分時候咱們都在調優SQL語句。shell

然而,MySQL的優化倒是始於觀察,並且有時候觀察幾分鐘,幾小時就能得出結論的,可能要觀察一天以上。數據庫

這麼作的目的很明顯,就是爲了幫助咱們定位問題所在。 好比:MySQL的負載會在固定的某個時間節點忽然暴漲,或者一請求某幾個頁面就產生了較爲明顯的延遲,甚至影響了隨後的各個請求等。緩存

觀察的手段有多種多樣,阿里雲有強大的RDS控制檯,也能夠自建一套監控平臺,最次的就是臨時跑個shell腳本,收集MySQL運行情況。 觀察的指標也不盡相同,最知名的 show status 命令列出的指標就能不下200個,因此觀察也要有所取捨。 常常受人關注的指標有當前鏈接數以及最大鏈接數,當前運行的線程數,慢查詢數量等。架構

2、分析

將觀察的結果作進一步分析,也就造成了不一樣的解決思路。框架

多是某個時間節點緩存失效,致使MySQL的負載激增,能夠設法將緩存失效的時間節點儘量均勻的分攤在一天24小時中,或者找個訪問量較少的時段刷新緩存。函數

多是SQL語句存在潛在問題,在某些狀況下會有性能問題,能夠用 show full processlist 定位是哪一個庫,也能夠開啓慢查詢,直接定位到有問題的SQL語句,使用explain分析語句執行計劃。可能加個索引能解決問題,也有可能join太多表,須要拆分查詢,也有可能單表體量過大,要拆表了。性能

多是機器自己性能問題,所謂「巧婦難爲無米之炊」,這個時候要考慮擴容了。測試

3、解決

在分析階段已經說起了大部分解決手段了,最後總結一下:優化

一、引入緩存,固然,這是一把雙刃劍,要想用的恰如其分,仍是須要必定的功力。緩存也分兩方面的,一方面是MySQL的內部緩存機制,MySQL提供了多種緩存參數的配置,好比查詢的結果集緩存,結果集排序的緩存,可根據實際狀況進行調整。另外一方面是MySQL以外的緩存,好比Redis+MySQL的架構,開啓了Hibernate(Mybatis)的緩存功能。緩存的引入無非是想減輕MySQL的查詢負擔,可是必須在性能穩定性與數據時效性之間取得平衡。阿里雲

二、SQL語句有性能問題,這種狀況時有發生,一般是上線以前未能作一個完整的基準測試,而只是簡單的功能性測試。當數據量積累到必定程度以後,SQL性能問題就集中爆發出來了。因此,在寫完SQL以後,要養成explain的習慣,將潛在的性能問題扼殺在萌芽中。固然,咱們也要避免「過分優化」,咱們要預見獲得一張表是讀取次數多,仍是更新次數多,數據量會不會爆發性增加,仍是增加十分緩慢。固然,寫SQL語句也要遵循必定的原則,好比何時用IN查詢,何時用EXISTS謂詞,在JOIN以前是否是能夠精簡一部分表數據,創建的索引可否正確派上用場……

三、必要的時候,能夠對機器進行擴容,固然系統的總體架構也能夠考慮進行優化,搭建MySQL集羣,可靠性和可用性都能獲得大幅提高。

4、補充:SQL範式

1NF

每個份量必須是不可分的數據項。

特色:

  • 有主鍵,且主鍵不能爲空。
  • 字段不能再分。

2NF

在範式一的基礎上,且每個非主屬性徹底函數依賴於碼。

特色:

  • 知足第一範式。
  • 表中的每個非主屬性,必須徹底依賴於本表碼。
  • 只有當一個表中,主碼由兩個或以上的屬性組成的時候,纔會出現不符合第二範式的狀況。

3NF

在知足第二範式的基礎上,且每個非主屬性既不部分依賴於碼也不傳遞依賴於碼。

特色:

  • 知足第二範式。
  • 非主屬性不能傳遞依賴於碼。

** BCNF**

在知足第三範式的基礎上,且不容許主鍵的一部分被另外一部分或其它部分決定。

特色:

  • 知足第三範式。
  • 全部非主屬性對每個碼都是徹底函數依賴。
  • 全部的主屬性對每個不包含它的碼,也是徹底函數依賴。
  • 沒有任何屬性徹底函數依賴於飛碼的任何一組屬性。

以上是對MySQL優化的框架性思考。

相關文章
相關標籤/搜索