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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...