SQL Server調優系列基礎篇(並行運算總結)

前言html

上三篇文章咱們介紹了查看查詢計劃的方式,以及一些經常使用的鏈接運算符、聯合運算符的優化技巧。多線程

本篇咱們分析SQL Server的並行運算,做爲多核計算機盛行的今天,SQL Server也會適時調整本身的查詢計劃,來適應硬件資源的擴展,充分利用硬件資源,最大限度的提升性能。併發

閒言少敘,直接進入本篇的正題。負載均衡

技術準備高併發

同前幾篇同樣,基於SQL Server2008R2版本,利用微軟的一個更簡潔的案例庫(Northwind)進行解析。post

1、並行運算符性能

在咱們平常所寫的T-SQL語句,並非全部的最優執行計劃都是同樣的,其最優的執行計劃的造成須要多方面的評估才能夠,大部分根據SQL Server自己所造成的統計信息,而後對造成的多個執行計劃進行評估,進而選出最優的執行方式。學習

在SQL Server根據庫內容造成的統計信息進行評估的同時,還要參照當前運行的硬件資源,有時候它認爲最優的方案可能當前硬件資源不支持,好比:內存限制、CPU限制、IO瓶頸等,因此執行計劃的優劣還要依賴於底層硬件。測試

當SQL Server發現某個處理的數據集比較大,耗費資源比較多時,但此時硬件存在多顆CPU時,SQL Server會嘗試使用並行的方法,把數據集拆分紅若干個,若干個線程同時處理,來提升總體效率。大數據

在SQL Server中能夠經過以下方法,設置SQL Server可用的CPU個數

默認SQL Server會自動選擇CPU個數,固然不排除某些狀況下,好比高併發的生產環境中,防止SQL Server獨佔全部CPU,因此提供了該配置的界面。

還有一個系統參數,就是咱們熟知的MAXDOP參數,也能夠更改此係統參數配置,該配置也能夠控制每一個運算符的並行數(記住:這裏是每一個運算符的,而非所有的),咱們來查看該參數

 這個並行運算符的設置數,指定的是每一個運算符的最大並行數,因此有時候咱們利用查看系統任務數的DMV視圖sys.dm_os_tasks來查看,極可能看到大於並行度的線程數據量,也就是說線程數據可能超過並行度,緣由就是兩個運算符從新劃分了數據,分配到不一樣的線程中。

這裏如沒特殊狀況的話,建議採用默認設置最佳。

咱們舉一個分組的例子,來理解並行運算

採用並行運算出了提高性能還有以下幾個優勢:

  • 不依賴於線程的數量,在運行時自動的添加或移除線程,在保證系統正常吞吐率的前提下達到一個性能最優值
  • 可以適應傾斜和負載均衡,好比一個線程運行速度比其它線程慢,這個線程要掃描或者運行的數量會自動減小,而其它跑的快的線程會相應提升任務數,因此總的執行時間就會平穩的減小,而非一個線程阻塞總體性能。

下面咱們來舉個例子,詳細的說明一下

並行計劃通常應用於數據量比較大的表,小表採用串行的效率是最高的,因此這裏咱們新建一個測試的大表,而後插入部分測試數據,咱們插入250000行,總體表超過6500頁,腳本以下

--新建表,創建主鍵,造成彙集索引
CREATE TABLE BigTable
(
   [KEY] INT,
   DATA INT,
   PAD CHAR(200),
   CONSTRAINT [PK1] PRIMARY KEY ([KEY])
)
GO
--批量插入測試數據250000行
SET NOCOUNT ON 
DECLARE @i INT
BEGIN TRAN
    SET @i=0
    WHILE @i<250000
    BEGIN
       INSERT BigTable VALUES(@i,@i,NULL)
       SET @i=@i+1
       IF @i%1000=0
       BEGIN
          COMMIT TRAN
          BEGIN TRAN
       END
END    
COMMIT TRAN
GO   

咱們來執行一個簡單查詢的腳本

SELECT [KEY],[DATA]
FROM BigTable

這裏對於這種查詢腳本,沒有任何篩選條件的狀況下,不必採用並行掃描,由於採用串行掃描的方式獲得數據的速度反而比並行掃描獲取的快,因此這裏採用了clustered scan的方式,咱們來加一個篩選條件看看

SELECT [KEY],[DATA]
FROM BigTable
WHERE DATA<1000

對於這個有篩選條件的T-SQL語句,這裏SQL Server果斷的採用的並行運算的方式,彙集索引也是並行掃描,由於我電腦爲4個邏輯CPU(實際上是2顆物理CPU,4線程),因此這裏使用的是4線程並行掃描四次表,每一個線程掃描一部分數據,而後彙總。

這裏總共用了4個線程,其中線程0爲調度線程,負責調度全部的其它線程,因此它不執行掃描,而線程1到線程4執行了這1000行的掃描!固然這裏數據量比較少,有的線程分配了0個任務,可是總得掃描次數爲4次,因此這4個線程是並行的掃描了這個表。

 

可能上面獲取的結果比較簡單,有的線程任務尚未給分配滿,咱們來找一個相對稍複雜的語句

SELECT MIN([DATA])
FROM BigTable

這個執行計劃挺簡單的,咱們依次從右邊向左分析,依次執行爲:

4個並行彙集索引掃描——>4個線程並行獲取出前當前線程的最小數——>執行4個最小數彙總——>執行流聚合獲取出4個數中的最小值——>輸出結果項。

而後4個線程,每一個線程一個流聚合獲取當前線程的最小數

而後,將這個四個最小值通過下一個「並行度」的運算符匯聚成一個表

而後下一個就是流聚合,從這個4行數據中獲取出最小值,進行輸出,關於流聚合咱們上一篇文章中已經介紹

以上就一個一個標準的多線程並行運算的過程。

 

上面的過程當中,由於咱們使用的並行彙集索引掃描數據,4個線程基本上是平均分攤了任務量,也就是說每一個線程掃描的數據量基本相等,下面咱們將一個線程使其處於忙碌狀態,看看SQL Server會不會將任務動態的平攤到其它幾個不忙碌的線程上。

咱們在來添加一個大數據量表,腳本以下

SELECT [KEY],[DATA],[PAD] 
INTO BigTable2
FROM BigTable

咱們來寫一個大量語句的查詢,使其佔用一個線程,而且咱們這裏強制指定只用一個線程運行

SELECT MIN(B1.[KEY]+B2.[KEY]) 
FROM BigTable B1 CROSS JOIN BigTable2 B2
OPTION(MAXDOP 1) 

以上代碼想跑出結果,就我這個電腦配置估計少說五分鐘以上,而且咱們還強行串行運算,速度可想而知,
咱們接着執行上面的獲取最小值的語句,查看執行計劃

SELECT MIN([DATA])
FROM BigTable

咱們在執行計劃中,查看到了彙集索引掃描的線程數量

能夠看到,線程1已經數量減小了近四分之的數據,而且從線程1到線程4,所掃描的數據量是依次增長的。

咱們上面的語句很明確的指定了MAXDOP爲1,理論上講只可能會影響一個線程,爲何這幾個線程都影響呢?其實這個緣由很簡單,個人電腦是物理CPU只有兩核,所謂的線程數只是超線程,因此非傳統意義上的真正的4核數,因此線程之間是互相影響的。

 

咱們來看一個並行鏈接操做的例子,咱們查看並行嵌套循環是怎樣利用資源的

SELECT B1.[KEY],B1.DATA,B2.DATA 
FROM BigTable B1 JOIN BigTable2 B2
ON B1.[KEY]=B2.[KEY]
WHERE B1.DATA<100

上面的語句中,咱們在BigTable中Key列存在彙集索引,而查詢條件中DATA列不存在,因此這裏確定爲彙集索引掃描,對數據進行查找

來看執行計劃

咱們依次來分析這個流程,結合文本的執行計劃分析更爲準確,從右邊依次向左分析

第一步,就是利用全表經過彙集索引掃描獲取出數據,由於這裏採用的並行的彙集索引掃描,咱們來看並行的線程數和掃描數

四個線程掃描,這裏線程3獲取出數據100行數據。

而後將這100行數據,從新分配線程,這裏每一個線程平均分配到25行數據

到此,咱們要獲取的結果已經均分紅4個線程共同執行,每一個線程分配了25行數據,下一步就是交給嵌套循環鏈接了,由於咱們上面的語句中須要從BigTable2中獲取數據行,因此這裏選擇了嵌套循環,依次掃描BigTable2獲取數據。

關於嵌套循環鏈接運算符,能夠參照個人第二篇文章。

咱們知道這是外表的循環數,也就是說這裏會有4個線程並行執行嵌套循環。若是每一個線程均分25行,數據那麼內部表就要執行

4*25=100次。

而後,執行完,嵌套掃描獲取結果後,下一步就是,將各個線程執行的結果經過並行運算符彙總,而後輸出

 上述過程就是一個並行嵌套循環的執行流程。充分利用了四核的硬件資源。

參考文獻

結語

此篇文章先到此吧,文章短一點,便於理解掌握,後續關於並行操做還有一部份內容,後續文章補充吧,本篇主要介紹了查詢計劃中的並行運算符,下一篇咱們接着補充一部分SQL Server中的並行運算,而後分析下咱們平常所寫的增刪改這些操做符的優化項,有興趣可提早關注,關於SQL Server性能調優的內容涉及面很廣,後續文章中依次展開分析。

有問題能夠留言或者私信,隨時恭候有興趣的童鞋加入SQL SERVER的深刻研究。共同窗習,一塊兒進步。

 

文章最後給出上一篇的鏈接

SQL Server調優系列基礎篇

SQL Server調優系列基礎篇(經常使用運算符總結)

SQL Server調優系列基礎篇(聯合運算符總結)

 

若是您看了本篇博客,以爲對您有所收穫,請不要吝嗇您的「推薦」。

相關文章
相關標籤/搜索