SQL性能优化整合持续更新
?
??? 性能優化是面試、程序員之間交流的重要話題。數據到了一定量級后和用戶達到一定數量頻繁的請求某些數據查詢等操作表,數據庫是成為優化的必經之路。眾說紛紜,打算從表設計到查詢、業務操作等方面入手。數據庫從設計到編碼到使用這些過程中,及早發現問題比到后面使用后找到問題付出的代價要小,隨著時間的發展,越晚發現問題付出的代價越大。
設計表結構時優化:
1)一般來說,數據庫的三大范式可以解決一部分的性能問題
第1規范:沒有重復的組或多值的列,這是數據庫設計的最低要求。
第2規范: 每個非關鍵字段必須依賴于主關鍵字,每張表必須有一個唯一的主鍵,不能依賴于一個組合式主關鍵字的某些組成部分。消除部分依賴,大部分情況下,數據庫設計都應該達到第二范式。
第3規范: 一個非關鍵字段不能依賴于另一個非關鍵字段,減少關聯關系中的數據冗余。消除傳遞依賴,達到第三范式應該是系統中大部分表的要求,除非一些特殊作用的表。
2)字段設計的時候,一定要注意字段選取的范圍,能用int類型的就不要使用varchar、nvarchar。text和img這些應該在高版本沒有了吧,慎重使用。就算要用,把他們用txt文件或者xml文件存到服務器,數據庫存鏈接就好。盡量滿足現在以后的數據長度。數據保存的時候盡量給默認值,因為查詢的時候要排除null,少一個查詢條件多一點速度。盡量減少自增字段,不利于數據遷移和并發量高等一些數據操作
?
3)盡量少使用表刪除更新聯動。表更新刪除聯動功能并不是一個線程安全的操作,如果用戶操作并發量大,那么極大可能會操作出錯而且這個錯誤系統是無法定位的,無法保證數據的完整性
4)合理使用觸發器,觸發器的使用完全是為了數據的完整性,用得合理事半功倍,而且還是個多線程操作。但是觸發器增多了也會對系統有負擔,尤其是那種操作頻繁的表
5)合理使用索引,索引像個目錄一樣,其數據結構是樹,查詢速度也是很可觀的。前期數據量少的時候感覺不出來,數據量一大起來,真的可以為所欲為。當然索引不是越多越好,合理就行
關于索引的選擇,應該注意:
1.根據數據量決定哪些表需要增加索引,數據量小的可以只選擇主鍵。
2.根據使用頻率決定哪些字段需要建立索引,選擇經常作為連接條件、篩選條件、聚合查詢、排序的字段作為索引的候選字段。
3.把經常一起出現的字段組合在一起,組成組合索引,組合索引的字段順序與主鍵一樣,也需要把最常用的字段放在前面,把重復率低的字段放在前面。
4.一個表不要加太多索引,因為索引影響插入和更新的速度。
?
6)如果考慮數據庫與項目服務器分離的時候盡量考慮硬件的內存帶寬和硬盤存儲量
7)當然主外鍵盡量少使用聯合主鍵或者外鍵,查詢數據的時候少一個條件也是一種速度的提升,也聽說過查詢速度跟聯合主鍵的位置也有一定的關系,這個正在考證。
8)在表設計的時候避免使用null,可以設置默認值,因為在做索引查詢的時候會消耗更多的內存,減少查詢時候的null排除操作
業務操作方面優化:
1)盡量少使用select *,勤快點用select a,b,c。。。,因為*是一個通配符,把所有的信息全部返回出來實行全表檢索,這樣增加不僅增加了內存消耗也會把一些不必要的字段暴露給客戶端,查詢的使用最好是把列名標記出來減少全表檢索
2)避免使用耗費資源的操作,帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎 執行,耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序
3)查詢的時候盡量減少時間轉換、字符拼接、數據類型轉換操作。當然必要合理不得已等情況下
4)統計select count(a)、select count(*)建議用select count(1)
5)where后面盡量少用 null判斷和少用case when,前面講過盡量給默認值。
6)where查詢的時候盡量避免索引字段的類型轉換、使用函數、數值計算或字符拼接。因為表頻繁刪除新增等操作索引有空缺,這些操作會給查詢帶來很重的負擔
7)避免多級的嵌套查詢:select (select count(1)from A)as a from (select * from (select a from a where))inner join ...
8)避免使用子查詢,having、in。。能用exists代替的、能用join等連接查詢代替。having和in真的是性能油老虎,全局反復查詢
9)在連接查詢條件里面能完成的,盡量不要到where里面去篩選,這樣兩次全局查詢很吃性能
10)避免使用行轉列操作,經常發現很多小伙伴做統計的時候腦袋都要炸了。。。我有個辦法,sql最好保存統計信息或者后端保存xml格式的統計信息,定時執行統計操作,把數據保存起來,尤其是這個統計信息操作比較頻繁的時候。很有效果
11)數據庫操作時,盡量不用游標,能用循環或者CASE WHEN轉換的盡量吧。
12)減少delete操作,原因很簡單,delete操作會破壞索引結構留下索引碎片需要定時清理,而且容易出現誤操作
13)適當的使用視圖,視圖本身就是一張虛擬表沒有實際的數據存儲,所以每次查詢視圖的時候系統會添加一個臨時表把這個視圖存入緩存中,一定時間后這個緩存被清理
14)盡量減少多表關聯,多表關聯非常影響查詢速度
15)一些復雜的數據結構處理應該放在前端或者后端處理,減少數據庫的開銷
16)合理使用like查詢,name like '%張三%'這樣的查詢執行不到索引,只有 name like '張%' 這樣的查詢才能執行到索引
17)查詢中or 、<>、!= 不會執行到索引,可以使用in來代替他們,當然in的數據匹配條數盡量不要超過200條
? ?? 在查詢階段我們一般是觀察這個查詢的執行計劃,看哪塊執行影響速度,然后有針對性的去優化它。還可以通過一些sql查詢監控獲取一些比較消耗內存的查詢和查詢次數較多的sql語句,適當的做計劃緩存,一把雙刃劍。
數據庫的優化,從設計就應該開始,找到問題減少以后發現問題執行的時間效率。優化應該要配合web、后端、數據庫、硬件這些方面來實施,甚至nosql,數據庫分布式,數據庫緩存等一些有效的方法提高數據訪問速度,提高用戶的使用效率。
?
總結
以上是生活随笔為你收集整理的SQL性能优化整合持续更新的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XCode调试错误
- 下一篇: Redis实现消息队列之生产消费模式