SQL Server 批次或工作排程

每個 SQL Server 執行個體都是獨立的作業系統處理序。每個執行個體都有可能處理上千個並行的使用者要求。SQL Server 的執行個體會使用 Microsoft Windows 的執行緒 (或若有設定,則使用 Fiber),以便有效地管理這些並行的工作。每個 SQL Server 執行個體永遠都會為系統處理序執行數個執行緒。這包含了每個伺服器網路程式庫的一或多個執行緒、處理網路 I/O 的網路執行緒以及與「服務控制管理員」通訊的單一執行緒。

了解排程

每個 SQL Server 執行個體都有實作與作業系統相似環境的內部層。內部層是用以在不需呼叫 Windows 核心的情況下來排程和同步處理並行的工作。內部層也可以有效地排程 Fiber 或 Windows 執行緒。每個 SQL Server 執行個體都會維持 Windows 執行緒集區或 Fiber 集區以處理使用者查詢。這個集區大小的最大值,是由 max worker threads 伺服器組態選項所控制。

若要了解如何處理要求或工作,有必要了解下列基本詞彙:

  • 連接
    當使用者成功地登入時就會建立連接。使用者就可以提交一或多個 Transact-SQL 陳述式來執行。當使用者明確登出時,就會關閉連接,或是終止連接。

  • 批次
    SQL 批次是一組從用戶端傳送到 SQL Server 執行個體執行的一或多個 Transact-SQL 陳述式。它代表使用者提交到 Database Engine 的工作單位。

  • 工作
    工作代表 SQL Server 所排程的工作單位。批次可對應到一或多個工作。例如,多個工作將可執行平行查詢。

  • Windows 執行緒
    每個 Windows 執行緒代表獨立的執行機制。

  • Fiber
    Fiber 是輕量型執行緒,所需的資源比 Windows 執行緒少,而且在使用者模式下可以切換內容。一個 Windows 執行緒可以對應到許多 Fiber。

  • 工作者執行緒
    工作者執行緒代表 SQL Server 的邏輯執行緒,在內部對應到 Windows 執行緒,或若輕量型共用設為 ON,則對應到 Fiber。對應會一直保持著,直到工作者執行緒因為記憶體壓力或是因為閒置很長的時間而取消配置為止。工作與工作者執行緒之間的關聯會在工作的存留期間保持著。

管理使用者連接與工作者執行緒的資源

雖然執行緒和 fiber 使用的資源不多,但它們仍然會消耗資源。在有成千上萬的使用者連接之系統中,每個連接若有一個工作者執行緒,所消耗的資源便足以降低 SQL Server 的效率。除此之外,為每個使用者連接配置專用的工作者執行緒是不必要的,因為大多數的連接實際只是花上大部分的時間來等待用戶端接收批次。反而是,SQL Server 的執行個體會使用工作者執行緒集區。工作者執行緒集區必須要夠大,才能服務在該執行個體中同一時間內正在執行批次的使用者連接數。使 max worker threads 選項保留其預設值 0,將可讓 SQL Server 的執行個體能有效地將使用者連接對應到數個工作者執行緒。這將可確保它們不會耗用太多資源。

設定 SQL Server 的 Fiber

伺服器組態選項輕量型共用,可控制 SQL Server 的執行個體是要使用 Windows 執行緒或 Fiber。此選項的預設值是 0。這表示 SQL Server 的執行個體會為每個工作者執行緒排程 Windows 執行緒,最多可設定為 max worker threads 選項中所設定的值。如果 [輕量型共用] 設定為 1,則 SQL Server 將使用 Fiber 而不是 Windows 執行緒。這便稱為以 Fiber 模式執行。在 Fiber 模式中,SQL Server 會為每個 SQL 排程器配置一個 Windows 執行緒,然後為每個工作者執行緒配置一個 Fiber,最多可至 max worker threads 選項中所設定的值。SQL Server 的執行個體不論是使用 Windows 執行緒或是 Fiber,都會使用相同的演算法來排程及同步處理工作。SQL Server Express 不支援 Fiber。如需詳細資訊,請參閱使用 lightweight pooling 選項。我們不建議您針對例行作業使用 Fiber 模式排程。這是因為 Fiber 模式可能會抑制一般環境切換的好處而降低效能,而且 SQL Server 的某些元件無法在 Fiber 模式下正確運作。如需詳細資訊,請參閱輕量型共用

批次或工作排程如何運作

當應用程式連接到 Database Engine 時,就會指定工作階段識別碼 (SPID)。連線期間所有要維護的資訊都會在與 SPID 相關聯的內部資料結構中管理。SQL Server 的執行個體會接收從用戶端而來的批次,然後將批次分成一或多個工作,接著將每個工作與工作者執行緒集區的可用工作者執行緒關聯。工作者執行緒將在工作的存留期間與工作繫結。工作者執行緒會在關聯的 SQL 排程器上執行要求。如果沒有任何可用的工作者執行緒,且尚未達到 max worker threads 值,則 SQL Server 執行個體會為新的批次配置新的工作者執行緒。如果沒有任何可用的執行緒或 Fiber,且已經達到 max worker threads 值,則 SQL Server 執行個體會阻止新的工作,直到釋放工作者執行緒為止。

當工作者與工作產生關聯後,它會保持與工作關聯的狀態,直到工作完成為止,例如,直到批次所產生的最後一個結果集傳回給用戶端為止。到那時,就可釋放工作者執行緒,並可用於與下一個批次相關聯的工作配對。

Database Engine 只有在收到批次到傳回結果給用戶端之間的時間,必須主動執行連接工作。在此期間,有時批次並不需要主動處理。例如,有時 Database Engine 必須等待讀取作業擷取目前查詢所需的資料,或是等待另一個批次釋放鎖定。甚至在工作被阻止使用某些資源期間,工作與工作者之間的關聯仍然維持著。

每當 Database Engine 開始處理與批次關聯的工作時,它會排程與工作關聯的工作者執行緒以執行工作。在工作者執行緒完成工作後,SQL Server 的執行個體就會將該工作者執行緒再分派給下一個已準備好要開始的工作。在連接的存留期間,連接的 SPID 仍然保持不變。長時間執行的連接可能會有許多不同的工作者執行緒,同時執行其個別的批次工作。例如,第一個批次的工作由 worker1 執行,而第二批次的工作則由 worker2 執行。有些陳述式是可以平行處理的。在此情況下,一個批次可能會有多個工作,並由多個工作者執行緒同時執行這些工作。