資料庫學習進階一
一:問題的產生:
在應用系統開發初期,由於開發資料庫資料比較少,對於查詢SQL語句,複雜檢視的的編寫等體會不出SQL語句各種寫法的效能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中資料的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的優化。對於海量資料,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的SQL語句,提高系統的可用性。
原因分析
主要原因1:後臺資料庫中的資料過多,沒做資料優化導致後臺查詢資料很慢
次要原因2:前端資料請求-解析-展示過程處理不當
次要原因3:網路問題所致
那麼我們應該怎麼做後臺資料優化呢?
1、快取,在持久層或持久層之上做快取
使用ehcache快取,這個一般用於持久層的快取,提供持久層、業務層的快速快取,hibenate預設使用的二級快取就是ehcache;
2、資料庫表的大欄位剝離
假如一個表的欄位數有100多個,學會拆分欄位,保證單條記錄的資料量很小;
3、恰當地使用索引
必要時建立多級索引,分析MySQL的執行計劃,通過表資料統計等方式協助資料庫走正確的查詢方式,該走索引就走索引,該走全表掃描就走全表掃描;
4、表的拆分
表分割槽和拆分,無論是業務邏輯上的拆分(如一個月一張報表、分庫)還是無業務含義的分割槽(如根據ID取模分割槽);
5、欄位冗餘
減少跨庫查詢和大表連線操作;,資料通過單個或多個JOB生成出來,減少實時查詢;
6、從磁碟上做文章
資料存放的在磁碟的內、外磁軌上,資料獲取的效率都是不一樣的;
7、放棄關係資料庫的某些特性
引入NoSQL資料庫;
換種思路存放資料,例如搜尋中的倒排表;
在上面談到資料庫查詢速度優化方案我們講到了,資料優化的幾種方案。接下來,一起看如何實際到具體的操作上.也就是我們在寫資料時我們應該注意些什麼?
1、對查詢進行優化,應儘可能避免全表掃描
首先應考慮在 where 及 order by 涉及的列上建立索引。
下面我們來以一個表中177條資料比較一下,全表掃描與建立索引之後效能的一個比較.
1.1 全表查詢
select * from table
1.2 建立索引查詢
select * from table where pay = 1 and order by enter
1.3 結論
從這兩種方式查詢資料庫結果看,建立索引之後查詢速度提高了些,現在資料量還不明顯,如果表中有10萬條速度,差異就會很明顯了.
2、寫資料語句時儘可能減少表的全域性掃描
2.1 減少where 欄位值null判斷
select * from table where pay_status = null;
如何這樣做,就會導致引擎放棄使用索引而進行全表掃描
應該這樣去設定(也就是在沒有值時,我們在存資料庫時自動預設給個o值,而不是什麼都不寫):
select * from table where pay_status = 0;
2.2 應儘量避免在 where 子句中使用!=或<>操作符
select * from table where pay_status != 0;
select * from table where pay_status <> null;
這樣寫將導致引擎放棄使用索引而進行全表掃描。
2.3 應儘量避免在 where 子句中使用 or 來連線條件
select * from table where pay_status != null or entertime = null;
這樣將導致引擎放棄使用索引而進行全表掃描
可以這樣操作:
select * from table where pay_status != null union all
select * from table where entertime = null;
2.4 in 和 not in 也要慎用
select * from table where rowed in [1,2,3,4];
或者
select * from table where rowed not in [1,2,3,4];
這樣操作,也會導致全表掃描
select * from table where rowed between 1 and 5;
2.5 少使用模糊匹配like
select * from table where entertime like '%2016-09-08%';
2.6 儘量避免在where子句中對欄位進行表示式操作
select * from table where rowed/4 = 100
這樣寫將導致引擎放棄使用索引進行全盤掃描
select * from table where rowed = 4*100
任何時候都不要用萬用字元去查詢所有
以萬用字元*去查詢所有資料,這樣做也是非常耗時的,我們應該需要什麼欄位就查詢什麼欄位.