01-sql优化及索引
掌握必要的sql優(yōu)化知識(shí)對(duì)于程序員來說是必須的,因?yàn)楦鞣N程序本質(zhì)來說就是對(duì)數(shù)據(jù)的處理,無非就是簡單的增刪改查和復(fù)雜的增刪改查而已,所以對(duì)于數(shù)據(jù)的分析處理是非常重要的
首先推薦一本書<深入淺出MYSQL>,由網(wǎng)易DBA團(tuán)隊(duì)編寫,寫的非常好,感興趣的朋友可以買來看看
下面介紹sql優(yōu)化:
1.主鍵查詢
查詢盡量使用主鍵查詢,因?yàn)橛兄麈I索引
其它索引后面介紹
2.合理使用字段,及字段長度
原則就是能保證存儲(chǔ)要求,也需預(yù)留空間
如果字段長度過長,會(huì)增加不必要的空間
例如郵政編碼字段,顯然VARCHAR(6)就行了,不需要VARCHAR(255)
3.盡量使用join關(guān)聯(lián)查詢替代子查詢
子查詢就是將一個(gè)查詢的結(jié)果作為另一個(gè)查詢的條件或者要查詢的表再次查詢
這樣查詢本質(zhì)上屬于兩次查詢了,mysql會(huì)創(chuàng)建臨時(shí)表來存儲(chǔ)第一次查詢結(jié)果,這樣會(huì)消耗空間
每次查詢都是要消耗資源的,所以這種效率不是很好
數(shù)據(jù)量小看不出來,數(shù)據(jù)量大的話使用關(guān)聯(lián)查詢速度更快,可以去試驗(yàn)
如果子查詢非要用的話,最好只出現(xiàn)一次,出現(xiàn)兩次或以上嚴(yán)重影響效率,因?yàn)橛?jì)算機(jī)會(huì)對(duì)sql語句生成執(zhí)行計(jì)劃,再去執(zhí)行,如果子查詢過多,人都看暈了,同樣計(jì)算機(jī)識(shí)別語句的意思,然后生成執(zhí)行計(jì)劃也會(huì)慢很多
4.網(wǎng)上看到有說使用外鍵的,工作中從來沒用過外鍵,這種說法不行,現(xiàn)在都是快速開發(fā)
外鍵的作用被業(yè)務(wù)層取代了,直接寫在代碼中
用外鍵不易修改/刪除數(shù)據(jù),很麻煩,實(shí)際開發(fā)中也很少/幾乎沒有公司使用外鍵
所以該方法不可取
5.少寫或不寫select * ,要什么字段就取什么字段
6.查詢緩存的使用
mysql默認(rèn)是開啟查詢緩存了
就是說相同的查詢,第二次會(huì)直接訪問緩存結(jié)果
但是有些sql中的函數(shù)如now(),這種是時(shí)時(shí)變化的,寫在sql語句中不會(huì)開啟查詢緩存
所以在sql中可不使用這些函數(shù)就不使用,用變量傳入sql中,這樣就開啟緩存了
7.當(dāng)只要一行數(shù)據(jù)時(shí)使用limit 1,mysql數(shù)據(jù)庫引擎會(huì)在找到一條數(shù)據(jù)后停止搜索,而不是繼續(xù)往后查找下一條符合的數(shù)據(jù),如果需的數(shù)據(jù)不是很多,但是返回量很大的時(shí)候也要使用limit限制返回量
8.使用EXPLAIN + 查詢語句可以知道sql語句執(zhí)行的信息
可以看出查詢掃描類型,這個(gè)后面介紹
也可以直接在客戶端navicat查看概況,里面會(huì)顯示查詢時(shí)間主要消耗在哪里...
9.在比如數(shù)據(jù)量小且固定的情況下,如性別,省市區(qū)等等,可以使用ENUM字段(枚舉),ENUM 類型是非常快的,它實(shí)際上保存的是TINYINT,但其外表上顯示為字符串..
10.復(fù)雜sql語句的拆分與避免鎖表
在訪問量很高的項(xiàng)目中/特別是互聯(lián)網(wǎng)項(xiàng)目中盡量避免寫復(fù)雜的sql語句,因?yàn)閺?fù)雜的sql語句執(zhí)行時(shí)間相對(duì)而言要長,會(huì)造成鎖表,就是說當(dāng)前sql執(zhí)行的這段時(shí)間,別的sql不能操作該表,在訪問量很高的網(wǎng)站上,這時(shí)就會(huì)有大量的sql操作請(qǐng)求積累在數(shù)據(jù)庫中,這樣很可能數(shù)據(jù)庫就崩了
11.建立索引(重點(diǎn))
這個(gè)是最重要的,因?yàn)椴挥盟饕陀盟饕牟樵兯俣认嗖盍藥资?br />如果不用索引,mysql會(huì)從第一條數(shù)據(jù)開始讀取,讀完整張表然后獲取需要的數(shù)據(jù)
用了索引,mysql會(huì)按照索引快速的到一個(gè)位置去手搜索數(shù)據(jù)
就把索引比作字典前面那些拼音筆畫索引,顯然用這個(gè)查比你拿著字典從第一頁一頁頁的翻要快的多
但是如果你獲取的是大部分?jǐn)?shù)據(jù),這時(shí)就是順序讀取要快了
索引分類:
主鍵索引
唯一索引
普通索引
最合適索引字段是常用于在where語句后的字段,也就是查詢條件
字段中值基數(shù)越大,越不同,索引效果越好,如果數(shù)據(jù)量小且值又很多相同的,效果就不明顯,就不需要用索引了
不要過度索引,因?yàn)轭~外的索引都是要占用磁盤空間的,修改表數(shù)據(jù)時(shí),索引必然是要更新的,這樣也是要浪費(fèi)時(shí)間的,還有sql生成執(zhí)行計(jì)劃的時(shí)候也會(huì)考慮各個(gè)索引,這樣看來多余的索引反而不好,不利于查詢優(yōu)化
12.EXPLAIN + 查詢語句分析
可以看到type:訪問類型,key:實(shí)際使用的索引,rows:掃描的行數(shù)
可以檢查設(shè)置的索引有沒有用到,掃描行數(shù)越少顯然速度越快了
訪問類型就是mysql是怎么找到所需的數(shù)據(jù)的
type分類:
all:
全表掃描,就是mysql從第一條數(shù)據(jù)開始,一條條查詢
index:
索引全掃描,就是遍歷整個(gè)索引查找
如:select title from film
title上有索引,但是根據(jù)的是所有的索引去查詢的數(shù)據(jù),這沒能很好體現(xiàn)索引的效果
range:
索引范圍掃描,常用于<,<=,>,between等操作符,就是設(shè)定索引值的范圍
如:select * from payment where customer_id <= 350
ref:
使用非唯一性索引匹配單個(gè)值然后返回
非唯一索引相對(duì)唯一索引而言的,唯一索引包括主鍵和設(shè)置其它唯一索引
如:select * from payment where customer_id = 350
eq_ref:
類似ref,但是使用的是唯一索引,對(duì)于每個(gè)索引鍵值,表中只一條記錄匹配,簡單的說就是多表連接中使用主鍵或者唯一性索引字段作為關(guān)聯(lián)條件
const/system:
最多匹配到一條數(shù)據(jù)
就是根據(jù)主鍵或者唯一性索引字段來查詢單表,速度最快
?
轉(zhuǎn)載于:https://www.cnblogs.com/jaro/p/8862165.html
總結(jié)
以上是生活随笔為你收集整理的01-sql优化及索引的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDK各版本新特性总结
- 下一篇: ES6 new syntax of De