問題查找及措施
問題查找
- 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺
- 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間
例如檔案上傳時,應將檔案上傳這一步放在事務外面
- 微軟建議
4.啟動sql定時執行計劃
怎么啟動sqlserver代理服務-百度經驗 (baidu.com)
- 啟動SQL Server Profiler,獲取耗時陳述句
- 部分陳述句可使用[資料庫引擎優化顧問]獲取優化意見,(存盤程序是不能的)
措施
- 首先你要知道是否跟sql陳述句有關,確保不是機器開不開機,服務器硬體配置太差
- 接著使用sql性能檢測工具--sql server profiler,分析出sql慢的相關陳述句,就是執行時間過長,占用系統資源,cpu過多的
- 通過下文《sql優化方法跟技巧》,避免一些不合理的sql陳述句,取暫優sql
- 再然后判斷是否使用了合理的統計資訊,sql server中可以自動統計表中的資料分布資訊,定時根據資料情況,更新統計資訊,是很有必要的
- 確認表中使用了合理的索引,見下文《索引》
- 資料太多的表,要磁區,縮小查找范圍
相關資料來源
sql陳述句的優化分析 - 張龍豪 - 博客園 (cnblogs.com)
sql優化(原理,方法,特點,實體) - -涂涂- - 博客園 (cnblogs.com)
sql優化方法跟技巧
select優化
1.保證不查詢多余的列與行,
- 盡量避免select * 的存在,使用具體的列代替*,避免多余的列
- 使用where限定具體要查詢的資料,避免多余的行
- 使用top,distinct關鍵字減少多余重復的行
2.慎用distinct關鍵字
distinct在查詢一個欄位或者很少欄位的情況下使用,會避免重復資料的出現,給查詢帶來優化效果,
但是查詢欄位很多的情況下使用,則會大大降低查詢效率
3.慎用union關鍵字
使用union all能對union進行一定的優化
4.判斷表中是否存在資料
禁用*號查數量,查是否存在:select count(*) from product
可以用:select top(1) id from product,查是否存在
- 6. 連接查詢的優化
減少連接表的資料數量可以提高效率
- 少使用like,及時要用可以僅在后面加一個%
- 復雜的運算,等取出來到客戶端后再處理
- 盡量使用多表查詢代替子查詢
- Order by 的列最好是索引列,最好不要是可為空的列,但是注意日期列不適合建索引,
- 排序影響性能(測驗,如果優化了,寫成通用的測C#)
- 先進行小表連接再大表
- 盡量減少直接的運算
14. 當在SQL陳述句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少決議的時間并減少那些由Column歧義引起的語法錯誤,
Where優化
1. 用EXISTS替代IN、用NOT EXISTS替代NOT IN:
(高效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')
(低效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB')
2. IS NULL 或IS NOT NULL操作(判斷欄位是否為空):用其它相同功能的操作運算代替,如:a is not null 改為 a>0 或a>’’等,不允許欄位為空,而用一個預設值代替空值,如申請中狀態欄位不允許為空,預設為申請,
3. Where后面條件的順序,將可以能更多排除資料減少資料量的條件放在最前面
4. 用EXISTS替換DISTINCT:
(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO
(高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
6.避免在索引列上使用計算
WHERE子句中,如果索引列是函式的一部分.優化器將不使用索引而使用全表掃描.舉例:
低效:
SELECT … FROM DEPT WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
7.用>=替代>
高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
兩者的區別在于, 前者DBMS將直接跳到第一個DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個DEPT大于3的記錄
Insert、update、delete優化
1.避免回圈插入、修改、洗掉
2.也避免超大批量的修改、洗掉
書寫規范
sql陳述句用大寫的;因為oracle總是先決議sql陳述句,把小寫的字母轉換成大寫的再執行,
其他
1.對查詢進行優化,要盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引
2. 對于多張大資料量(這里幾百條就算大了)的表JOIN,要先分頁再JOIN,否則邏輯讀會很高,性能很差
3. count(*)要杜絕
4.如果使用到了臨時表,在存盤程序的最后務必將所有的臨時表顯式洗掉,先 truncate table ,然后 drop table ,這樣可以避免系統表的較長時間鎖定
5.在新建臨時表時,如果一次性插入資料量很大,那么可以使用 select into 代替 create table,避免造成大量 log
6. 盡量避免使用游標操作大量的資料行
索引
措施
1. 決議SQL陳述句, 估算索引的利用率
2. 查詢優化統計資訊,由sql自動創建的,也可以自建
Create Statistics的作用 - 吾非無心 - 博客園 (cnblogs.com)
未確認項
1.總是使用索引的第一個列:
如果索引是建立在多個列上, 只有在它的第一個列(leading column)被where子句參考時,優化器才會選擇使用該索引. 這也是一條簡單而重要的規則,當僅參考索引的第二個列時,優化器使用了全表掃描而忽略了索引
2.因為索引需要額外的存盤空間和處理,那些不必要的索引反而會使查詢反應時間變慢.,定期的重構索引是有必要的(有待確認)
SQL Server 索引重建腳本 - 每天進步多一點 - 博客園 (cnblogs.com)
注意事項
1.盡量不要對索引列進行計算、型別改變,否則相當于索引無效
2.盡量不要對索引列使用!= ,not 等,否則相當于索引無效
優化目標
sqlserver性能調優中的邏輯讀,物理讀,預讀是什么意思 - Jearay - 博客園 (cnblogs.com)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/550601.html
標籤:SQL Server