10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議

上傳人:ta****fu 文檔編號(hào):199336172 上傳時(shí)間:2023-04-10 格式:DOCX 頁數(shù):10 大?。?97.02KB
收藏 版權(quán)申訴 舉報(bào) 下載
10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議_第1頁
第1頁 / 共10頁
10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議_第2頁
第2頁 / 共10頁
10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議_第3頁
第3頁 / 共10頁

下載文檔到電腦,查找使用更方便

9.98 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議》由會(huì)員分享,可在線閱讀,更多相關(guān)《10大sql書寫規(guī)范實(shí)戰(zhàn)技巧sql書寫優(yōu)化建議(10頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。

1、SQL調(diào)優(yōu) | SQL 書寫規(guī)范及優(yōu)化技巧10 個(gè)sql書寫規(guī)范及優(yōu)化技巧:一、 使用延遲查詢優(yōu)化 limit offset, rows經(jīng)常出現(xiàn)類似以下的 SQL 語句:SELECT * FROM film LIMIT 100000, 10offset 特別大!這是我司出現(xiàn)很多慢 SQL 的主要原因之一,尤其是在跑任務(wù)需要分頁執(zhí)行時(shí),經(jīng)常跑著跑著 offset 就跑到幾十萬了,導(dǎo)致任務(wù)越跑越慢。LIMIT 能很好地解決分頁問題,但如果 offset 過大的話,會(huì)造成嚴(yán)重的性能問題,原因主要是因?yàn)?MySQL 每次會(huì)把一整行都掃描出來,掃描 offset 遍,找到 offset 之后會(huì)拋棄 of

2、fset 之前的數(shù)據(jù),再從 offset 開始讀取 10 條數(shù)據(jù),顯然,這樣的讀取方式問題??梢酝ㄟ^延遲查詢的方式來優(yōu)化假設(shè)有以下 SQL,有組合索引(sex, rating)SELECT FROM profiles where sex=M order by rating limit 100000, 10;則上述寫法可以改成如下寫法這里利用了覆蓋索引的特性,先從覆蓋索引中獲取 100010 個(gè) id,再丟充掉前 100000 條 id,保留最后 10 個(gè) id 即可,丟掉 100000 條 id 不是什么大的開銷,所以這樣可以顯著提升性能二、 利用 LIMIT 1 取得唯一行數(shù)據(jù)庫引擎只要發(fā)現(xiàn)

3、滿足條件的一行數(shù)據(jù)則立即停止掃描,這種情況適用于只需查找一條滿足條件的數(shù)據(jù)的情況三、 注意組合索引,要符合最左匹配原則才能生效假設(shè)存在這樣順序的一個(gè)聯(lián)合索引“col_1, col_2, col_3”。這時(shí),指定條件的順序就很重要。前面兩條會(huì)命中索引,第三條由于沒有先匹配 col_1,導(dǎo)致無法命中索引, 另外如果無法保證查詢條件里列的順序與索引一致,可以考慮將聯(lián)合索引 拆分為多個(gè)索引。四、使用 LIKE 謂詞時(shí),只有前方一致的匹配才能用到索引(最左匹配原則)上例中,只有第三條會(huì)命中索引,前面兩條進(jìn)行后方一致或中間一致的匹配無法命中索引五、 簡單字符串表達(dá)式模型字符串可以使用 _ 時(shí), 盡可能避免

4、使用 %, 假設(shè)某一列上為 char(5)不推薦推薦六、盡量使用自增 id 作為主鍵比如現(xiàn)在有一個(gè)用戶表,有人說身份證是唯一的,也可以用作主鍵,理論上確實(shí)可以,不過用身份證作主鍵的話,一是占用空間相對于自增主鍵大了很多,二是很容易引起頻繁的頁分裂,造成性能問題(什么是頁分裂,請參考這篇文章)主鍵選擇的幾個(gè)原則:自增,盡量小,不要對主鍵進(jìn)行修改七、如何優(yōu)化 count(*)使用以下 sql 會(huì)導(dǎo)致慢查詢原因是會(huì)造成全表掃描,有人說COUNT(*)不是會(huì)利用主鍵索引去查找嗎,怎么還會(huì)慢,這就要談到 MySQL 中的聚簇索引和非聚簇索引了,聚簇索引葉子節(jié)點(diǎn)上存有主鍵值+整行數(shù)據(jù),非聚簇索葉子節(jié)點(diǎn)上則

5、存有輔助索引的列值 + 主鍵值,如下所以就算對 COUNT(*) 使用主鍵查找,由于每次取出主鍵索引的葉子節(jié)點(diǎn)時(shí),取的是一整行的數(shù)據(jù),效率必然不高,但是非聚簇索引葉子節(jié)點(diǎn)只存儲(chǔ)了列值 + 主鍵值,這也啟發(fā)我們可以用非聚簇索引來優(yōu)化,假設(shè)表有一列叫 status, 為其加上索引后,可以用以下語句優(yōu)化:SELECT COUNT(status) FROM SomeTable有人曾經(jīng)測過(見文末參考鏈接),假設(shè)有 100 萬行數(shù)據(jù),使用聚簇索引來查找行數(shù)的,比使用 COUNT(*) 查找速度快 10 幾倍。不過需要注意的是通過這種方式無法計(jì)算出 status 值為 null 的那些行如果主鍵是連續(xù)的,

6、可以利用 MAX(id) 來查找,MAX 也利用到了索引,只需要定位到最大 id 即可,性能極好,如下,秒現(xiàn)結(jié)果SELECT MAX(id) FROM SomeTable說句題句話,有人說用 MyISAM 引擎調(diào)用 COUNT(*) 非???,那是因?yàn)樗崆鞍研袛?shù)存在磁盤中了,直接拿,當(dāng)然很快,不過如果有 WHERE 的限制八、避免使用 SELECT * ,盡量利用覆蓋索引來優(yōu)化性能SELECT *會(huì)提取出一整行的數(shù)據(jù),如果查詢條件中用的是組合索引進(jìn)行查找,還會(huì)導(dǎo)致回表(先根據(jù)組合索引找到葉子節(jié)點(diǎn),再根據(jù)葉子節(jié)點(diǎn)上的主鍵回表查詢一整行),降低性能,而如果我們所要的數(shù)據(jù)就在組合索引里,只需讀取組合

7、索引列,這樣網(wǎng)絡(luò)帶寬將大大減少,假設(shè)有組合索引列 (col_1, col_2)推薦用SELECT col_1, col_2 FROM SomeTable WHERE col_1 = xxx AND col_2 = xxx不推薦用SELECT * FROM SomeTable WHERE col_1 = xxx AND col_2 = xxx九、 如有必要,使用 force index() 強(qiáng)制走某個(gè)索引業(yè)務(wù)團(tuán)隊(duì)曾經(jīng)出現(xiàn)類似以下的慢 SQL 查詢post_id 也加了索引,理論上走 post_id 索引會(huì)很快查詢出來,但實(shí)現(xiàn)了通過 EXPLAIN 發(fā)現(xiàn)走的卻是 id 的索引(這里隱含了一個(gè)常見考

8、點(diǎn),在多個(gè)索引的情況下, MySQL 會(huì)如何選擇索引),而 id 0 這個(gè)查詢條件沒啥用,直接導(dǎo)致了全表掃描, 所以在有多個(gè)索引的情況下一定要慎用,可以使用 force index 來強(qiáng)制走某個(gè)索引,以這個(gè)例子為例,可以強(qiáng)制走 post_id 索引,效果立桿見影。這種由于表中有多個(gè)索引導(dǎo)致 MySQL 誤選索引造成慢查詢的情況在業(yè)務(wù)中也是非常常見,一方面是表索引太多,另一方面也是由于 SQL 語句本身太過復(fù)雜導(dǎo)致, 針對本例這種復(fù)雜的 SQL 查詢,其實(shí)用 ElasticSearch 搜索引擎來查找更合適,有機(jī)會(huì)到時(shí)出一篇文章說說。十、 使用 EXPLAIN 來查看 SQL 執(zhí)行計(jì)劃上個(gè)點(diǎn)說了

9、,可以使用 EXPLAIN 來分析 SQL 的執(zhí)行情況,如怎么發(fā)現(xiàn)上文中的最左匹配原則不生效呢,執(zhí)行 EXPLAIN + SQL 語句可以發(fā)現(xiàn) key 為 None ,說明確實(shí)沒有命中索引我司在提供 SQL 查詢的同時(shí),也貼心地加了一個(gè) EXPLAIN 功能及 sql 的優(yōu)化建議,建議各大公司效仿 _,如圖示十一、 批量插入,速度更快當(dāng)需要插入數(shù)據(jù)時(shí),批量插入比逐條插入性能更高推薦用- 批量插入INSERT INTO TABLE (id, user_id, title) VALUES (1, 2, a),(2,3,b);不推薦用INSERT INTO TABLE (id, user_id, t

10、itle) VALUES (1, 2, a);INSERT INTO TABLE (id, user_id, title) VALUES (2,3,b);批量插入 SQL 執(zhí)行效率高的主要原因是合并后日志量 MySQL 的 binlog 和 innodb 的事務(wù)讓日志減少了,降低日志刷盤的數(shù)據(jù)量和頻率,從而提高了效率十二、 慢日志 SQL 定位前面我們多次說了 SQL 的慢查詢,那么該怎么定位這些慢查詢 SQL 呢,主要用到了以下幾個(gè)參數(shù)這幾個(gè)參數(shù)一定要配好,再根據(jù)每條慢查詢對癥下藥,像我司每天都會(huì)把這些慢查詢提取出來通過郵件給形式發(fā)送給各個(gè)業(yè)務(wù)團(tuán)隊(duì),以幫忙定位解決總結(jié)業(yè)務(wù)生產(chǎn)中可能還有很多 CASE 導(dǎo)致了慢查詢,其實(shí)細(xì)細(xì)品一下,都會(huì)發(fā)現(xiàn)這些都和 MySQL 索引的底層數(shù)據(jù) B+ 樹 有莫大的關(guān)系,強(qiáng)烈建議大家看一下我的另一篇介紹 B+ 樹的文章,好評如潮!相信大家看了之后,以上出現(xiàn)的問題會(huì)有一個(gè)更深層次的理解,掌握底層,以不變應(yīng)萬變!

展開閱讀全文
溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔
關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!