SQL性能優化

来源:http://www.cnblogs.com/ysyn/archive/2016/05/01/5445064.html
-Advertisement-
Play Games

引言: 以前在面試的過程中,總有面試官問道:你做過sql性能優化嗎?對此,我的答覆是沒有。一次沒有不是自己的錯誤,兩次也不是,但如果是多次呢?今天痛下決心,把有關sql性能優化的相關知識總結一下,以便在不久的將來,我的回答不是“沒有”,總能多多少少說一些東西。算是長進吧。說到性能優化,本人感覺到有必 ...


引言:  

  以前在面試的過程中,總有面試官問道:你做過sql性能優化嗎?對此,我的答覆是沒有。一次沒有不是自己的錯誤,兩次也不是,但如果是多次呢?今天痛下決心,把有關sql性能優化的相關知識總結一下,以便在不久的將來,我的回答不是“沒有”,總能多多少少說一些東西。算是長進吧。說到性能優化,本人感覺到有必要先瞭解sql語句的執行順序,因為對優化或多或少的會有些幫助。

 

sql語句執行順序:  

  sql語句和其他相關的編程語言最大不同的地方應該是執行順序。對於大多數編程語言來說都是按照順序進行執行,但對於sql語句,儘管select是最開始出現,但幾乎總是最後一個執行,最開始執行的往往是from子句。每一步驟產生一個虛擬表,這些虛擬表對於調用者來說是不能用的,僅僅作用於下一步驟,而只有最後的查詢結果表才能被調用者所使用。當有步驟沒有出現時便跳過該執行步驟。下麵上代碼:

(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)        ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>

邏輯查詢處理階段簡介:

1)from:對FROM子句中的前兩個表執行笛卡爾積(Cartesian product)(交叉聯接),生成虛擬表VT1

2)on:對VT1應用ON篩選器。只有那些使<join_condition>為真的行才被插入VT2

3)outer(join):如 果指定了OUTER JOIN(相對於CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部聯接把左表標記為保留表,右外部聯接把右表標記為保留表,完全外部聯接把兩個表都標記為保留表)中未找到匹配的行將作為外部行添加到 VT2,生成VT3.如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重覆執行步驟1到步驟3,直到處理完所有的表為止。

4)where:對VT3應用WHERE篩選器。只有使<where_condition>為true的行才被插入VT4.

5)group by:按GROUP BY子句中的列列表對VT4中的行分組,生成VT5.

6)cube|roolup:把超組(Suppergroups)插入VT5,生成VT6.

7)having:對VT6應用HAVING篩選器。只有使<having_condition>為true的組才會被插入VT7.

8)select:處理SELECT列表,產生VT8.

9)distinct:將重覆的行從VT8中移除,產生VT9.

10)order by:將VT9中的行按ORDER BY 子句中的列列表排序,生成游標(VC10)

11)top:從VC10的開始處選擇指定數量或比例的行,生成表VT11,並返回調用者。

註:

步驟10,按ORDER BY子句中的列列表排序上步返回的行,返回游標VC10.這一步是第一步也是唯一一步可以使用SELECT列表中的列別名的步驟。這一步不同於其它步驟的 是,它不返回有效的表,而是返回一個游標。SQL是基於集合理論的。集合不會預先對它的行排序,它只是成員的邏輯集合,成員的順序無關緊要。對錶進行排序 的查詢可以返回一個對象,包含按特定物理順序組織的行。ANSI把這種對象稱為游標。理解這一步是正確理解SQL的基礎。

因為這一步不返回表(而是返回游標),使用了ORDER BY子句的查詢不能用作表表達式。表表達式包括:視圖、內聯表值函數、子查詢、派生表和共用表達式。它的結果必須返回給期望得到物理記錄的客戶端應用程式。

  在SQL中,表表達式中不允許使用帶有ORDER BY子句的查詢,而在T—SQL中卻有一個例外(應用TOP選項)。所以要記住,不要為表中的行假設任何特定的順序。換句話說,除非你確定要有序行,否則不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要執行有序索引掃描或使用排序運行符。

   sql語句執行時是按照從右到左的順序處理from子句中的表名,from子句中寫在最後的表也即是基礎表將被最先處理,因此在from子句中包含多個表的情況下,選擇記錄條數最少的表作為基礎表,在某種程度上將會極大的提高其性能。如果有3個以上的表,則選擇交叉表作為基礎表。此處對性能優化來說相當重要。

  

執行計劃:

說完執行順序後,便討論下執行計劃:

執行計劃是資料庫根據SQL語句和相關表的統計信息作出的一個查詢方案,這個方案是由查詢優化器自動分析產生的,比如一條SQL語句如果用來從一個 10萬條記錄的表中查1條記錄,那查詢優化器會選擇“索引查找”方式,如果該表進行了歸檔,當前只剩下5000條記錄了,那查詢優化器就會改變方案,採用 “全表掃描”方式。

可見,執行計劃並不是固定的,它是“個性化的”。產生一個正確的“執行計劃”有兩點很重要:

(1)    SQL語句是否清晰地告訴查詢優化器它想乾什麼?

(2)    查詢優化器得到的資料庫統計信息是否是最新的、正確的?

 

優化檢測工具:

  基礎知識介紹完畢了,開始性能優化,但是我們怎麼才能知道該系統中的那些sql語句應該進行性能優化,該語句是否應該進行系統優化,查看相關資料,針對sqlserver,找到sqlserver資料庫對應的有個sql server profiler,使用該工具可以找到針對某個資料庫表來說,有什麼樣的操作行為拉低了其性能。

打開系統主菜單--sqlserver幾---性能工具--->>sql server profiler;

然後文件--新建跟蹤--顯示跟蹤屬性視窗;

首先那個select%是個篩選監測的TextData。那個%是個通配符,他的意思就是篩選select開口的語句。當然這你自己可以隨便定義,如update%,delete%....。

把那個排除不包含值的行也給帶上,然後確定,運行。然後在資料庫中運行一句select。你會發現他檢測到啦。

1.查找持續時間最長的查詢

一般情況下,最長查詢時間的查詢語句就是最影響性能的原因存在。它不僅占用資料庫引擎大量的時間,還浪費系統資源,還影響資料庫應用系統的交互速度。再對數據用應用系統進行優化時,先找出他,對其優化,在創建跟蹤時,勾上TSQL-SQL:BatchCompleted.跟Stored Procedures-RPC:completed。這樣就能找出來這個最長時間查詢然後對其進行分析優化。

select TextData,Duration,CPU from <跟蹤的表>
where EventClass=12 -- 等於12表示BatchCompleted事件
and CPU<(0.4*Duration)  --如果cpu的占用時間,小於執行sql語句時間的40%,說明該語句等待時間過長

2.最占用系統資源的查詢

就是占用cpu時間,跟讀寫IO的次數。建議事件包含Connect、Disconnect、ExistingConnection、SQL:BatchCompleted、RPC:completed,列包含writes,reads,cpu。

3.檢測死鎖

在訪問量,併發量都很大的資料庫中,如果設計稍不合理,就有可能造成死鎖,給系統性能帶來影響。事件包含:RPC:Starting、SQL:BatchStarting、Lock:DeadLock(死鎖事件)、Lock:DeadLockChaining(死鎖的事件序列)。

查閱SqlServer性能檢測和優化工具使用詳細

 

資料庫引擎優化顧問

和sql server profiler相對於的有個“資料庫引擎優化顧問”,也是一個與性能優化有關的工具,可以抽時間瞭解瞭解。瞭解後再補充吧。

 

sql性能優化常見經驗:

下麵總結下載網上各個大牛們認為進行sql優化應該操作的事項:

1、模糊查詢like。

使用like進行模糊查詢時應該特別註意,這個很基本,基本上大家都知道。呵呵

select*from contact where username like ‘%yue%’

關鍵詞%yue%,由於yue前面用到了“%”,因此該查詢必然走全表掃描,除非必要,否則不要在關鍵詞前加%。

2、where條件查詢

儘量避免使用in,not in,having,可以使用 exist 和not exist代替 in和not in。不要以字元格式聲明數字,要以數字格式聲明字元值。

3、前面提到的from子句中有多個表進行關聯查詢時

在from子句中包含多個表的情況下,選擇記錄條數最少的表作為基礎表,在某種程度上將會極大的提高其性能。如果有3個以上的表,則選擇交叉表作為基礎表

4、select *查詢

儘量不要使用

select * from tablename

取而代之的則是:

select columnname1,columnname2 from tablename

5、排序操作

避免使用耗費資源的操作,帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎 執行,耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序。

6、索引表操作

對於此處,個人還沒有弄明白,首先對於索引還不明白,那麼性能優化更談不上了。反正很多大牛都是操作索引表,需要特別註意。以後明白了再補充吧。

...

7、統一規範sql語句

編寫規範的sql語句,這一點是最重要的一點,不管對於系統還是個人來說,都是相當的重要。

不規範的有:

很複雜的sql語句,對於編寫者自己都暈了。

大小寫隨意編寫,對於系統來說是個小麻煩。

肯定還有,就是平時多註意就ok了。

 

參考:

SqlServer性能檢測和優化工具使用詳細

高手詳解SQL性能優化十條經驗

優化SQL查詢:如何寫出高性能SQL語句

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 設計索引的原則1. 搜索的索引列,不一定是所要選擇的列。換句話說,最適合索引的列是出現在WHERE子句中的列,或連接子句中指定的列,而不是出現在SELECT 關鍵字後的選擇列表中的列。 2. 使用惟一索引。考慮某列中值的分佈。對於惟一值的列,索引的效果最好,而具有多個重覆值的列,其索引效果最差。例如 ...
  • 1. 關於Cluster cluster_known_nodes:4 cluster_size:3 說明集群中總共有4個節點;集群的size是3,相當於3個主節點參與了槽位分配 ...
  • 今天瀏覽百度,看到一篇關於MySql資料庫優化的經驗,看了大概懂,就成自己的了 優化你的MySQL查詢緩存 在MySQL伺服器上進行查詢,可以啟用高速查詢緩存。讓資料庫引擎在後臺悄悄的處理是提高性能的最有效方法之一。當同一個查詢被執行多次時,如果結果是從緩存中提取,那是相當快的。 但主要的問題是,它 ...
  • MHA是一款開源的MySQL高可用程式,為MySQL主從複製架構提供了節點故障轉移功能,當 master發生故障時MHA會自動提升擁有最新數據的slave節點成為新的節點,還提供了master節 點的線上切換功能,即按需切換master/slave節點 Manager會時刻監視主節點,並把主節點的二 ...
  • 消息隊列就是一個消息的鏈表。 可以把消息看作一個記錄,具有特定的格式以及特定的優先順序。對消息隊列有寫許可權的進程可以向消息隊列中按照一定的規則添加新消息;對消息隊列有讀許可權的進程則可以從消息隊列中讀走消息。消息隊列是隨內核持續的。 消息隊列的類型: POSIX消息隊列以及系統V消息隊列,系統V消息隊列 ...
  • 最近需要搭建FTP伺服器,順著書上的教程走一遍流程。 1. 安裝FTP服務 圖一 圖二 圖三 可以看到上面提示並未啟動windows自動更新,這個需要註意一下。 2. 新建FTP站點 準備FTP文件夾: 圖四 開始新建站點: 圖五 圖六 此步由於沒有SSL證書所以選擇無。 圖七 這裡給予所有用戶讀取 ...
  • Linux下安裝程式,一般都通過包管理器安裝,但是包管理器或軟體商店裡的軟體往往不是最新版本的,安裝最新版軟體時通常是下載源代碼進行編譯。 編譯安裝源代碼時就離不開make了,但是make是單線程的,運行速度慢,發揮不了多核CPU和超線程技術的優勢。 在編譯程式的時候使用 -j 參數可以大大提高編譯 ...
  • 問題描述 1、首先讓我們先看一張圖 2、從圖中,我們可以很清楚的看到當http請求的站點訪問https的資源的時候會報出“Cross-Origin”跨域的問題。為什麼會出現這樣的錯誤,這是因為涉及到“同源策略”的問題。。。blablabla…… 3、下麵依次說如何解決這個問題 問題解決 1、我們再來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...