今年所做的優化,大的涉及到體系架構改造,涉及到利用cache,涉及到更改實現方式,小的如加hint,建索引更改sql語句等,一年下來,大大小小算下來也超過100個了。我稍微總結一下優化要具備什么,怎么來做?
為什么要優化?
舉個簡單的例子,某個sql每小時執行了300萬次,邏輯讀如果我們能從500下降到100,每小時就可以節省了上億個邏輯讀,優化可以讓服務器更節約資源,優化可以讓sql執行速度更快,提高用戶體驗。
1.理論一定要扎實。
數據庫基礎知識要扎實。比如索引為什么有些塊delete后不能重用,而表delete后這些塊很快會被重用掉的?想象索引B樹 樹狀結果,想象關系型數據庫heap表的最大特點是什么,就很容易理解上述問題了。
我一直認為會什么不重要,重要的是有扎實的基本功,勤奮,態度。態度能決定一切,很多東西要通過時間來沉淀的。葉開以前跟我說過,statspack中每個sql該排在報表中的哪個位置,我們是要清清楚楚的,這樣出現問題時很容易快速定位出來。
2.怎么去判定sql的好壞?
通過邏輯讀大小是很難斷定sql是否優化,看是很難看出來的,要結合業務,返回的數據量來判斷。
舉個例子,web分頁語句每頁顯示20行,單次邏輯讀消耗在60左右,每小時執行次數在300萬左右,這種sql的性能要學會評估,假設20行各分散在不同的塊上,取20行的數據最多需要20個塊+索引掃描取rowid 差不多在3-10個塊左右,這個sql消耗的邏輯讀差不多也就在30個塊左右,邏輯讀在60左右肯定是高了,如果我們能優化到30左右,每小時節省的邏輯讀在300萬執行次數*30,差不多節省了1個億的邏輯讀。我們這種系統中,有些sql每小時執行次數在百萬級別之上,甚至在達到千萬級別,sql優化要特別重視,也很有效。
3.理解分頁list的兩種寫法
基本上是必修課了,有不用這個功能的應用嗎?分頁對于oracle來說有兩種寫法:普通寫法和rowid寫法,要深刻理解這兩個寫法,特別是rowid寫法,優勢是什么,用在哪個地方,具體的可以參考http://www.taobaodba.com,里面有多篇文章。
4.更改sql的實現方式
基本上我是禁止大表之間的關聯查詢的,如果核心表出現這種問題,我是堅決要求改掉,很多時候我寧愿開發拆成兩個sql,分兩次來執行。舉個例子,比如匯總表(sborder_biz)和明細表(sborder_detail)是一對多的關系,一個匯總存在多個明細,我一般都是建議在明細表做的足夠詳細,做到不需要關聯匯總表來實現。大家可以想象一下,關聯兩個大表,一個表走索引(t2.it_id索引)另一個表只能走關聯的鍵值(t1.orderid)了,進而回表,對于oltp型的數據庫來說,記錄是非常分散的,回表的代價很大,t2返回多少條記錄,就需要去回表t1的多少記錄。
select t1.order_id,t2.createdate,t2.deleted from sborder_biz t1, sborder_detail t2
where t1.order_id = t2.order_id and t1.deleted = 0 and t2.it_id = :1 and t2.code = :2
5.建合適的索引
建合適的索引,特別是聯合索引,需要很多技巧的,要根據查詢條件,根據索引列的數據分布來建立,聯合索引的好壞對sql性能影響非常大。
6.不用is null條件。
建表時,列要盡量設置成not null,盡量設置成不為空。
7.關注細節,關注應用實現方式
是的,一定要多關注細節,從小事做起,我認為這是最重要的。
小時候去河里揀田螺,一次一小顆,什么時候才能揀到一籃呢,優化也是,我們這么大的系統,剛開始優化很難出效果的,做好每一個sql,關注每一個sql的實現方式,積少成多,當你埋頭在揀田螺時,籃子也漸漸滿了。
稍微總結了這么幾條,其他的會慢慢補充,比如如何使用cache,核心表如何設計等等,實際上面我所提到的幾條,任何一條是否能做好,對數據庫的性能影響都是極大的。
老大說我很多思想過于理想化,是的,架構,設計都不是我的專長,如果我都能看出問題來,那說明這不是小問題。通常我所負責的應用,我一般會去評估未來3-6個月的表現,進而加以改進,要多多未雨綢繆。
原文轉自:http://blogread.cn/it/article/66