文章轉載自「開發者圓桌」一個關於開發者入門、進階、踩坑的微信公衆號數據庫
SQL即結構化查詢語言(Structured Query Language),是一種特殊目的的編程語言,是一種數據庫查詢和程序設計語言,用於存取數據以及查詢、更新和管理關係型數據庫系統。編程
從接觸編程到如今一直從事和數據庫相關的工做,SQL是我使用時間最長的程序語言,沒有之一。緩存
關於SQL優化的文章網上不少,很具體,寫的很不錯,這裏再也不贅述。這篇文章將會結合平時工做中遇到的問題和經驗心得來闡述如何作好SQL優化,其中有錯誤和不足的地方,還請你們糾正補充。微信
對於數據庫優化有兩個層面,一是SQL優化,屬於業務層優化;一是數據庫設計、表空間規劃、緩存等屬於管理層面的優化,咱們這裏只討論SQL優化這個層面。併發
接受挑戰數據庫設計
不要被運行效率低下或者複雜的SQL嚇倒,要敢於接收它的挑戰,問題很明確就是要把這個SQL優化快一點,解決方法確定比遇到的問題多。編程語言
越是運行慢,越是複雜的SQL優化的空間就越大。工具
分析場景優化
數據處理大體能夠分紅兩大類:聯機事務處理OLTP(on-line transaction processing)、聯機分析處理OLAP(On-Line Analytical Processing)。OLTP是傳統的關係型數據庫的主要應用,主要是基本的、平常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持複雜的分析操做,側重決策支持,而且提供直觀易懂的查詢結果。 設計
OLTP 系統強調數據庫內存效率,強調內存各類指標的命令率,強調綁定變量,強調併發操做,對於SQL的執行效率有很高的要求;
OLAP 系統則強調數據分析,強調SQL執行時機,強調磁盤I/O,強調分區等。
OLTP要求事務一致性和快速執行,SQL執行時間通常以毫秒或者秒爲單位;OLAP對事務一致性要求不高,SQL執行時間以分鐘或者小時爲單位。所以,不一樣的業務場景,SQL優化的方法也是不一樣的。
定位SQL優化點
因爲數據庫產品、參數配置甚至同一款產品的不一樣發行版本都會致使同一條SQL出現不一樣的運行效率。隨着業務數據的增加,本來運行良好的SQL也會出現瓶頸。
變化再多也有規律可循,SQL運行效率低根本的問題就是SQL表關聯太多、SQL邏輯太複雜、表數據量太大、未使用索引等,這些就是咱們要優化的點。
拿到運行效率低的SQL之後,要分析一下該條SQL用到哪些表?哪些索引?表中的數據量是多少?對整個SQL運行的基礎環境有一個清晰的認識。
優化SQL最經常使用的輔助工具就是數據庫自己提供的「執行計劃」,如何開啓、使用執行計劃分析和優化SQL,可點擊文章最後左下角「閱讀原文」查看以前整理的一篇關於《數據庫SQL執行計劃應用初探》的文章。
進行SQL優化
定位到SQL執行效率低下的緣由之後,要想辦法優化它,下面是一些通用的處理思路,能夠參考一二。
索引;索引是關係型數據庫中SQL優化的利器,設計良好的索引以及在SQL中正確應用索引基本上能解決大部分的SQL優化問題。能夠經過執行計劃分析SQL中索引的應用狀況。
變通;3+6與4+5的結果都是9,作事的方式並非惟一的,可能一種SQL寫法效率很低,然而你換一個思路試試其餘的寫法,效率會有很大的提高,這個須要不斷的嘗試和摸索。
舉個栗子,以Oracle爲例查詢公司男性與女性員工的薪資總和
select
(select sum(salary) from employee where sex='男') 男性薪資總和,
(select sum(salary) from employee where sex='女') 女性薪資總和
from dual
更好的寫法應該是
select
sum(case when sex='男' then salary else 0 end) 男性薪資總和,
sum(case when sex='女' then salary else 0 end) 女性薪資總和
from employee
我剛入門SQL時,就是採用了第一種寫法,邏輯最簡單明瞭,可是一個employee表卻被掃描了兩次(在沒有索引的狀況下),隨着數據量的增長,這條SQL必然出現效率低的問題,第二種寫法就會優化不少,效率更高。這是一個簡單不能再簡單的變通了(固然是如今看來,當時可能想不到)。
分解;把複雜的一條SQL能夠拆解爲多條簡單SQL分步驟執行,可能你會以爲分步驟執行作了不少額外的工做,可是每條簡單的SQL執行的會很是快,總體上提高了SQL執行效率。
SQL分解最經常使用的就是建立中間表,中間表只保存須要的字段和數據行,同時增長必要的索引,可大大提高SQL的執行效率。
環境;SQL優化要在同一個環境中進行,不一樣的環境中SQL執行路徑多是不一樣的,優化的方法也是不一樣的。儘可能排除環境因素對SQL優化的影響。
經驗;經驗很重要,可是避免陷入經驗主義。你可能在Oracle中有着很是豐富的SQL優化經驗,可是在DB2數據庫中可能就不靈了,不要糾結,這很正常。在我從Oracle數據庫轉向DB2數據庫時就出現了不少問題,在Oracle中積累的經驗轉移到DB2中行不通,只能另闢蹊徑。
SQL優化須要經驗,可是不能太依賴經驗,要不斷調整本身的思路。每款數據庫產品都有本身的特色,要了解它們,而後去不斷應用。好在大部分的經驗是通用的,只是略加調整便可,不要太大壓力。
把平時優化SQL的技巧和方法總結下來,在真實的SQL優化場景中反覆使用和調整,逐漸造成本身的一套優化經驗。
總結
上面總結了一些我我的的SQL優化經驗,包治百病的良藥是不存在的,具體問題仍是須要當事人具體分析,優化思路是相通的。
SQL優化這事兒不須要刻意爲之,當你寫的SQL不知足業務要求時天然就要優化,每次的SQL優化都會不斷提高你的優化能力和思考方式。