數據庫優化是在後端開發中必備技能,今天寫一篇MySQL數據優化的總結,供你們看看mysql
1、MySQL數據庫優化分類sql
咱們經過一個圖片形式來看看數據優化一些策略問題數據庫
不難看出,優化有兩條路能夠選擇:硬件與技術。若是是投入硬件方式來優化成本至關高,若是是經過技術方式來優化效果好後端
2、測試數據樣例:你們能夠參考mysql官方的sakina數據庫數組
3、提升mysql千萬級大數據SQL查詢優化幾條經驗函數
1. 對查詢進行優化,應儘可能避免全表掃描,首先應考慮在where及order by 涉及的列上建立索引。由於:索引對查詢的速度有着相當重要的影響測試
2. 儘可能避免在where字句中對字段進行null值的判斷。不然將會致使引擎放棄使用索引而進行全表掃描 大數據
例如:select id from user where num is null 。能夠將num是這個字段設置默認值0.確保表中沒有null值,而後在進行查詢。修正後的SQL以下:select id from user where num=0優化
爲何須要儘可能去除null,而將這個字段設置默認值0,你們能夠看看下面的分析spa
考慮以下狀況,假設數據庫中一個表有10^6條記錄,DBMS的頁面大小爲4K,並存儲100條記錄。若是沒有索引,查詢將對整個表進行掃描,最壞的狀況下,若是全部數據頁都不在內存,須要讀取10^4個頁面,若是這10^4個頁面在磁盤上隨機分佈,須要進行10^4次I/O,假設磁盤每次I/O時間爲10ms(忽略數據傳輸時間),則總共須要100s(但實際上要好不少不少)。若是對之創建B-Tree索引,則只須要進行log100(10^6)=3次頁面讀取,最壞狀況下耗時30ms。這就是索引帶來的效果,不少時候,當你的應用程序進行SQL查詢速度很慢時,應該想一想是否能夠建索引
3. 應儘可能避免在where子句中使用!=或者是<>操做符號。不然引擎將放棄使用索引,進而進行全表掃描
4. 應儘可能避免在where子句中使用or來鏈接條件,不然致使放棄使用索引而進行全表掃描。可使用 union 或者是 union all代替
例如: select id from user where num =10 or num =20 這個語句景緻使引擎放棄num索引,而要全表掃描來進行處理的
解決方式:使用union 或者是 union all來代替
select id from user where num = 10; union all select id from user where num =20;
5. in 和 not in 也要慎用,不然將會致使全表掃描
若是 in 對於連續的數組,可使用between ...and.來代替
例如:select id from user where num in (1,2,3); 像這樣連續的就可使用between ...and...來代替了 select id from user where num between 1 and 3;
6. like使用需注意
下面這個查詢也將致使全表查詢:select id from user where name like '%三';
若是想提升效率,能夠考慮到全文檢索。好比solr或是luncene。而solr和luncenc是Java中最經常使用的全文檢索的技術
而下面這個查詢卻使用到了索引:select id from user where name like '張%';
7. where子句參數使用時候需注意
若是在where子句中使用參數,也會致使全表掃描。由於sql只會在運行時纔會解析局部變量。但優化程序不能將訪問計劃的選擇推遲到運行時;必須在編譯時候進行選擇。然而,若是在編譯時創建訪問計劃,變量的值仍是未知大,於是沒法做爲索引選擇輸入項
8. 儘可能避免在where子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描
例如:select id from user where num/2=100; 應修改成: select id from user where num = 100*2;
9. 儘可能避免愛where子句中對字段進行函數操做,這將致使引擎放棄索引,而進行全表掃描
例如: select id from user substring(name,1,3) = 'abc' ,這句sql的含義其實就是,查詢name以abc開頭的用戶id
應修改成: select id from user where name like 'abc%';
10. 不要在where子句中的"="左邊進行函數、算術運算或是使用其餘表達式運算,不然系統可能沒法正確使用索引
11. 不少時候用exists 代替 in是一個很好的選擇
好比: select num from user where num in(select num from newTable);
可使用下面語句代替: select num from user a where exists(select num from newTable b where b.num = a.num );
12. 索引建立需注意
並不是索引建立越多越好。索引當然能夠提升相應的查詢效率,可是一樣會下降insert以及update的效率。由於在insert或是update的時候有可能會重建索引或是修改索引。因此索引怎樣建立須要慎重考慮,視狀況而定。一個表中因此數量最好不要超過6個。若太多,則須要考慮一些不經常使用的列上建立索引是否有必要
13. 並非全部索引對查詢都有效,sql是根據表中數據進行查詢優化的,當索引lie(索引字段)有大量重複數據的時候,sql查詢可能不會去利用索引。如一表中字段 sex、male、female 幾乎各一半。那麼即便在sex上建立了索引對查詢效率也起不了多大做用