如何資料庫效能優化不不講解!

2021-10-09 10:02:51 字數 4822 閱讀 7927

tsql語法習慣和規範

1,tsql語法習慣和規範(一切不是教條主義)

目標:編寫健壯的sql語句,生成更加高效的執行計畫

所有的效能優化中,理論基礎固然重要,但往往經驗比理論更重要;經驗說明你踩過的坑多;但解決問題的能力也建立在你的知識積累和思考

你可以嘗試建立一些爛表,爛資料結構,然後嘗試優化它

優秀的資料結構往往反映了你的領域模型

查詢語句

下面我們以以下這條查詢語句來分析sql的語法規範:

userinfo表,10萬行資料,主鍵id,非聚集索引usercode

employee表,100萬行資料,無任何索引

employee表中有乙個userid欄位,用於記錄employee對應的user   12

3select * from userinfo as a

join employee as b on a.id=b.userid

where a.username=『cmliu』

1,需要明確需要返回的字段;盡可能避免"select *"語句

減少io資料量

提高索引的覆蓋,提高索引的使用率

2,需要限定返回集合資料量;尤其是資料量比較大的時候

防止大批量的資料操作

有效使用索引

防止掃瞄操作帶來大量的磁碟io和記憶體開銷

考慮一下,那些需要返回全部資料的業務場景是否是合理的,是否可以用其他方案替代;

大資料量時全部資料返回來,使用者能看得過來嗎?是否可以折中或者替代

3,優先考慮使用索引;在需要對資料進行過濾的時候,優先考慮使用索引字段

如果存在多個索引字段,那麼我們優先考慮選擇重複率最低的索引字段

一般情況下,我們會選擇重複率不超過5%的字段作為索引字段

4,過濾欄位上不要使用任何計算,包括函式邏輯計算

計算會照成查詢優化器無法使用計算欄位的索引

按上面規範優化之後12

3select top 10 a.username,a.usercode,b.employeename from userinfo as a

join employee as b on a.id=b.userid

where a.usercode=『cmliu』

4,order by:order by 子句的效能取決於參與排序的資料量的大小

控制排序資料集的大小,排序是在資料篩選的結果完成後進行排序的,避免大資料量的排序操作

排序消耗的資源超過記憶體限制時,排序過程中則會使用到tempdb,此時效能會大大下降

因為tempdb是公共的,大批量資料排序甚至會導致整個系統出現大量的sql效能下降

使用索引,尤其是必須針對大批量資料排序操作時

排序合理使用索引甚至可以在查詢過程中不發生排序

5,資料量級

大批量的資料操作會導致將查詢中的大量資料從記憶體拆分到tempdb,tempdb是公共的,是儲存在磁碟上的,這會增加io消耗

大批量的資料操作會清理快取,會使快取失效

資料量級建立在資料庫伺服器硬體資源,網路資源的效能與資料結構設計上

對於有些系統來說100萬行就是大資料量,而針對有些系統來說1000萬行都是小資料量

行業裡面一般情況下將千萬級,億級資料量定為大資料量;常見的大資料量主要集中在流水,記錄等這些業務方面;如支付流水,訂單流水,交易流水,訪問款流水,倉庫流水,定位記錄等

6,group by

group by對資料進行分組統計時,也要使用排序演算法;所以對於order by的優化是對group by的優化是一樣的;

所以group by過程中可能會發生hash計算或者排序計算,如果你在group by的字段合理的索引,就可以避免雜湊計算和排序;如下圖

考慮限制參與group by的資料量;因為發生hash計算時,大資料量會更加消耗資源

在全欄位group by時,你會發現group by與distinct是一致的;因為本質上distinct在計算時,就是進行一次全字段的group by;對比以下兩個sql語句的執行結果與執行計畫,你就會明白

注,下面的userid,age是有索引的,所以在group by時沒有發生排序12

select distinct userid,age from sortusers

select userid,age from sortusers group by userid,age

update語句

update語句執行時也會查詢目標資料;和select相比;它們在鎖方面有差異

update會對資料優先新增【更新鎖】,確認要進行修改時,【更新鎖】轉換成【排他鎖】;然後才會更新資料

select使用的共享鎖,update的排它鎖,更新鎖比共享鎖的相容性更低;

update在更新大資料量的時候,或者update存在效能問題時,或者update長時間執行的,或者在乙個事務中時,容易照成阻塞。

update的優化

優先照顧update語句;在更新頻繁,或者大資料量的更新時;優先考慮update的效能,避免長時間阻塞,如update的索引,使用唯一欄位來進行篩選過濾的資料

delete語句

delete語句檢索資料的效能和select是一樣的

delete刪除資料時,使用【排他鎖】

delete刪除資料時,會影響到索引的維護,對效能的要求更高;

delete刪除語句的查詢字段使用索引時,應該權衡更新,查詢,刪除操作的頻率;不要因為過多的索引影響資料的刪除,更新的效能

delete刪除資料時,為了保證acid,會對刪除的資料記錄日誌;大批量的資料刪除會造成大量的日誌記錄,會影響效能

where子句

sql的優化通常都是針對具有條件過濾(where)的語句進行的;沒有過濾條件的查詢語句只能選擇表掃瞄或者索引掃瞄

where語句優化

是否有合適的索引可供使用

字段是否有函式計算

返回字段集合(是否按需返回,返回的字段是否有索引)

返回資料量

關聯查詢

巢狀迴圈是查詢連線中最好的一種方式,以小資料集作為外部資料,大資料集作為內部迴圈的集合

連線查詢的連線字段優先使用索引字段,重複率低的字段

巢狀連線以小表掃瞄(優先考慮索引掃瞄),大表查詢為佳(優先考慮索引查詢)

資料集相當且已排序時,使用合併連線

索引是寶貴的,也是昂貴,出現效能問題時,不是立馬對參與關聯查詢的所有表,所有參與查詢或者連線欄位健索引;而是找乙個表,給1到2個字段建立索引;

在大部分情況下(不要盲目),對大表建立索引的價效比會比較高。

雜湊連線演算法偽**表示(實際上就是笛卡爾積):12

3456

78910

1112

13foreach(var r1 in 小表)

foreach(var r2 in 大表)}}

子查詢子查詢盡量集中在where子句中,方便閱讀

在乙個與劇中,子查詢數量不超過3個,整個查詢語句涉及的表不超過5個

子查詢的語句會被執行計畫分解,簡化,特殊的轉換,轉成常用的連線操作

在特殊的情況下,子查詢不能被優化或者簡化,在這些情況下,子查詢會優先執行,作為下乙個操作的輸入部分

過於複雜的子查詢會造成效能上的瓶頸

避免在子查詢中對大資料集進行彙總或者排序操作

盡量縮小子查詢中可能返回的結果集範圍

優先考慮使用確定性的判斷符(等於,in,exsit),避免使用any,all

exist在子查詢中通常會轉換成inner join

in在子查詢中通常會直接轉換成連線運算子

如下示例圖

效能優化工具

sqlserver2017具有自動優化功能

sqlserver2017智慧型查詢處理:自使用查詢處理

效能監控和優化

查詢儲存

查詢儲存是資料庫效能優化的基礎,當sql效能出現問題,而我們是無法獲取這個sql的執行計畫;

而查詢儲存就是收集當時的執行資訊儲存在磁碟中,

包括執行計畫,執行時統計資訊,等待資訊;

你可以在查詢儲存中看到耗時的查詢,回歸的查詢等

qlserver2017開啟查詢儲存會對資料庫造成3%-5%的效能影響;預設情況下是不開啟的

sqlserver2017開啟查詢儲存方法一:使用sql

1set query_store = on (operation_mode = read_write);

sqlserver2017開啟查詢儲存方法二:在sql server mangement studio中,選擇要監控的資料庫,右鍵"屬性",在屬性面版中,選擇查詢儲存》操作模式,修改值為"讀寫"

在資料查詢儲存的配置面板上有乙個資料重新整理間隔;預設15分鐘,資料重新整理間隔小會影響到資料庫效能

查詢儲存的結果

執行計畫回歸

執行計畫可能會因為記憶體的壓力清除,也可能會因為資料的趨勢,索引而變更;

執行計畫的變更會可能導致相同的sql語句採用不同的執行計畫;一般情況下,新的執行計畫會比舊的執行計畫要好

也存在新的執行計畫沒有舊的執行計畫好的情況;這樣新的執行計畫就會導致效能回歸;

在沒有查詢儲存的情況下,我們是無法發現執行計畫回歸的;查詢回歸,

引數嗅探

sqlserver編譯sql時會評估傳入的引數,生成對應的執行計畫快取,引數值會儲存在執行計畫快取中

自動優化

對潛在查詢效能問題進行深入分析,並提供優化建議;自動選擇更好的執行計畫;當資料庫引擎發現更好的執行計畫時,會自動更正執行計畫

sql server要執行多次來蒐集執行計畫的資訊

影響執行計畫質量的因素:統計資訊果實,不合理的索引,低效的sql語句,**重編譯

自學習,持續監控

開啟自動調優sql:12

alter database current

set auto_tuning(force_last_good_plan=on);

如何優化資料庫?提高資料庫的效能

1.對語句的優化 用程式中,保證在實現功能的基礎上,儘量減少對資料庫的訪問次數 通過搜尋引數,儘量減少對錶的訪問行數,最小化結果集,從而減輕網路負擔 能夠分開的操作盡量分開處理,提高每次的響應速度 在資料視窗使用sql時,盡量把使用 的索引放在選擇的首列 演算法的結構盡量簡單 在查詢時,不要過多地使...

資料庫效能優化

資料庫設計 實現sql server資料庫的優化,首先要有乙個好的資料庫設計方案。在實際工作中,許多sql server方案往往是由於資料庫設計得不好導致效能很差。實現良好的資料庫設計必須考慮這些問題 1.邏輯資料庫規範化問題 一般來說,邏輯資料庫設計會滿足規範化的前3級標準 第1規範 沒有重複的組...

資料庫效能優化

1 系統設計 1 縱向 橫向分割表,減少表的尺寸 縱向 欄位多。按業務主題分割。根據頁大小。橫向 資料多。按條件分割表。eg 按年儲存表,歷史資料表和當期資料更新表。2 將資料處理交給db,編寫儲存過程 1 減少網路的開銷 2 儲存過程是編譯 優化過,速度快。3 唯讀查詢操作優化方法 1 資料量小的...