SQL Server橫向擴充:設計,實現與維護(3)- 分散式資料分割檢視的實現
在上一篇文章中,我們已經說到分散式資料分割檢視採用的是Linked Server技術實現,也大致的說了下它的實現原理,我們這裡對實現的內部機制點到為止,我們本系列的目的在於實戰和分析各種技術方案的使用情境。
一般而言,我們常常會使用SQL Profiler來對Linked Server進行故障排除和效能最佳化。在SQL Server 2005以及之後版本中,增強了查看Linked Server工作情況的事件。通過Profiler,我們可以看到OLE DB調用其他資料庫伺服器的資訊。
查詢的執行過程
其實,分散式資料分割檢視就是將一個查詢中的產生的查詢樹的一部分傳遞到遠端資料庫中。這個道理大家應該很容易想到。在SQL Server 2000中,一個查詢的啟動命令和查詢的擷取資料行命令不能並行的進行。在SQL Server 2005以及以後,命令的啟動可以並行的執行,而且遠端資料庫的串連池和重疊使用的I/O是經過最佳化了的。但是,依然不能並行的執行命令去擷取資料。
大家可能不是太明白這裡的講述,我下面就舉個簡單的例子說明下:
假設現在有一個使用了Linked Server的查詢,那麼產生的查詢樹(注意,這裡是查詢樹,是邏輯的文法樹,還不是執行計畫)我們假設如下:
QQ20121128081422.png(18.17 K)11/28/2012 8:16:20 AM
大家看到圖中標註紅色的部分,代表了這裡的查詢樹需要最終去遠端資料庫上面執行。
當查詢樹產生好了之後,就需要去執行,此時,這個查詢樹就要被分拆到不同的遠端資料庫上面去,此時在2005中,假設上面的查詢樹需要串連4個不同的遠端資料庫,那麼此時,那麼,此時,就可以並行的啟動四個查詢的命令,然後這些命令將各自的查詢樹結構傳遞過去。然後這些查詢樹就會交給遠端資料庫查詢引擎去最佳化,然後執行,之後遠端資料庫就會把資料傳送回來,但是此時這個4個遠端資料庫不能同時傳送資料,只能一個個的來。
而且,在這個過程中SQL Server OLE DB會把“擷取的資料行的統計資訊”發送到遠端SQL Server中,去協助遠端資料庫的查詢處理器更好的工作,從而使得,從遠程情況下,允許有統計查詢處理器執行相同的查詢與本地查詢的成本估算和最佳化,並選擇最有效整體查詢計劃。
實現分散式資料分割檢視
要實現分散式資料分割檢視,我們就需要使用Linked Server,為了建立Linked Server,我們可以使用很多的方式:直接使用圖形化的SSMS介面,然後中物件瀏覽器中建立;使用sp_addlinkedserver這個預存程序。
在SSMS中,我們可以很容易的申明要串連的資料庫執行個體的名字,而且還需要將Server Type設定為SQL Server。使用SSMS建立Linked Server的時候,很多的配置都是採用預設值,但是當使用sp_addlinkedserver的時候,我們需要配置相關的參數,特別是要設定svrproduct,這個參數的值必須是SQL Server。
下面就看個例子,使用預存程序建立的,代碼如下:
-- on instance A
USE MASTER
GO
EXECUTE sp_addlinkedserver 'ServerB', N'SQL Server'
GO
-- on instance B
USE MASTER
GO
EXECUTE sp_addlinkedserver 'ServerA', N'SQL Server'
GO
然後,我們需要在每個資料庫中都去建立相同的資料表,因為我們現在示範的例子是把一個表中的資料拆分放在不同的伺服器上面(當然,我們還可以把原本在一個資料庫的表放在不同的資料庫中)。當我們把一個表拆分放在不同的資料庫時,需要制定一個拆分的條件,這一點和我們在SQL Server 2005的分區表中使用資料分割配置類似,但是這裡的分區是分布式的,例如,對於Customer表,我們把CustomerID作為拆分的列,如下:
-- on instance A
USE SalesDB
GO
CREATE TABLE SalesSchema.Customers1to4 (
-- partitioning column
CustomerId INTEGER PRIMARY KEY
CHECK (CustomerID BETWEEN 1 AND 49999),
-- other columns…
)
-- on instance B
USE SalesDB
GO
CREATE TABLE SalesSchema.Customers5to9 (
-- partitioning column
CustomerId INTEGER PRIMARY KEY
CHECK (CustomerID BETWEEN 50000 AND 99999),
-- other columns…
)
-- on instance A
USE SalesDB
GO
CREATE TABLE SalesSchema.Customers1to4 (
-- partitioning column
CustomerId INTEGER PRIMARY KEY
CHECK (CustomerID BETWEEN 1 AND 49999),
-- other columns…
)
-- on instance B
USE SalesDB
GO
CREATE TABLE SalesSchema.Customers5to9 (
-- partitioning column
CustomerId INTEGER PRIMARY KEY
CHECK (CustomerID BETWEEN 50000 AND 99999),
-- other columns…
)
上面的代碼應該很好理解:把CustomerID從1到49999的使用者放在資料庫執行個體A中,50000-99999的使用者放在B中。
資料分布好了之後,我們就需要去建立視圖,從而嚮應用程式那邊隱藏內部的實現,代碼如下:
-- on instance A
USE SalesDB
GO
CREATE VIEW AllCustomers AS
SELECT * FROM SalesDB.SalesSchema.Customers1to4
UNION ALL
SELECT * FROM ServerB.SalesDB.SalesSchema.Customers5to9
)
-- on instance B
USE SalesDB
GO
CREATE VIEW AllCustomers AS
SELECT * FROM ServerA.SalesDB.SalesSchema.Customers1to4
UNION ALL
SELECT * FROM SalesDB.SalesSchema.Customers5to9
)
下面就講解安全相關設定。 暫時就到這裡,更多請看
【免費試讀】可擴充SQL Server架構設計與實戰系列(1)
【免費試讀】可擴充SQL Server架構設計與實戰系列(2)-為什麼要擴充資料庫