與葉節點、一元、二元或 n 元運算子不同,「分散式運算子」會在多個伺服器中執行。
以下運算子屬於分散式運算子:
資料庫結構定義
本頁的查詢和執行計畫是根據下列資料庫結構定義:
CREATE TABLE Singers (
SingerId INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
SingerInfo BYTES(MAX),
BirthDate DATE
) PRIMARY KEY(SingerId);
CREATE INDEX SingersByFirstLastName ON Singers(FirstName, LastName);
CREATE TABLE Albums (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
AlbumTitle STRING(MAX),
MarketingBudget INT64
) PRIMARY KEY(SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);
CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget);
CREATE TABLE Songs (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
TrackId INT64 NOT NULL,
SongName STRING(MAX),
Duration INT64,
SongGenre STRING(25)
) PRIMARY KEY(SingerId, AlbumId, TrackId),
INTERLEAVE IN PARENT Albums ON DELETE CASCADE;
CREATE INDEX SongsBySingerAlbumSongNameDesc ON Songs(SingerId, AlbumId, SongName DESC), INTERLEAVE IN Albums;
CREATE INDEX SongsBySongName ON Songs(SongName);
CREATE TABLE Concerts (
VenueId INT64 NOT NULL,
SingerId INT64 NOT NULL,
ConcertDate DATE NOT NULL,
BeginTime TIMESTAMP,
EndTime TIMESTAMP,
TicketPrices ARRAY<INT64>
) PRIMARY KEY(VenueId, SingerId, ConcertDate);
您可以使用下列資料操縱語言 (DML) 陳述式,將資料新增至這些資料表:
INSERT INTO Singers (SingerId, FirstName, LastName, BirthDate)
VALUES (1, "Marc", "Richards", "1970-09-03"),
(2, "Catalina", "Smith", "1990-08-17"),
(3, "Alice", "Trentor", "1991-10-02"),
(4, "Lea", "Martin", "1991-11-09"),
(5, "David", "Lomond", "1977-01-29");
INSERT INTO Albums (SingerId, AlbumId, AlbumTitle)
VALUES (1, 1, "Total Junk"),
(1, 2, "Go, Go, Go"),
(2, 1, "Green"),
(2, 2, "Forever Hold Your Peace"),
(2, 3, "Terrified"),
(3, 1, "Nothing To Do With Me"),
(4, 1, "Play");
INSERT INTO Songs (SingerId, AlbumId, TrackId, SongName, Duration, SongGenre)
VALUES (2, 1, 1, "Let's Get Back Together", 182, "COUNTRY"),
(2, 1, 2, "Starting Again", 156, "ROCK"),
(2, 1, 3, "I Knew You Were Magic", 294, "BLUES"),
(2, 1, 4, "42", 185, "CLASSICAL"),
(2, 1, 5, "Blue", 238, "BLUES"),
(2, 1, 6, "Nothing Is The Same", 303, "BLUES"),
(2, 1, 7, "The Second Time", 255, "ROCK"),
(2, 3, 1, "Fight Story", 194, "ROCK"),
(3, 1, 1, "Not About The Guitar", 278, "BLUES");
distributed union 運算子是從 distributed cross apply 和 distributed outer apply 擷取而來的原始運算子
執行計畫中的分散式運算子在一或多個本機 distributed union 變數的上方,會有一個 distributed union 變數。distributed union 變數會執行子計畫的遠端分配作業。
本機分散式聯集變數會位於查詢所執行的每個掃描的上方。當動態變更的分割界線重新啟動時,本機 distributed union 變數可確保查詢執行的穩定性。雖然這個運算子會從視覺化計畫中隱藏,但一律會存在。
distributed union 變數會盡可能使用分割述詞進行分割修剪。分割修剪是指遠端伺服器只會在滿足述詞的分割上執行子計畫,藉此縮短延遲時間並提升查詢效能。
Distributed union
「distributed union」運算子在概念上將一或多個資料表分到多個分割,並在每個分割上個別遠端評估子查詢,然後聯集所有結果。
下列查詢會示範這個運算子:
SELECT s.songname,
s.songgenre
FROM songs AS s
WHERE s.singerid = 2
AND s.songgenre = 'ROCK';
/*-----------------+-----------+
| SongName | SongGenre |
+-----------------+-----------+
| Starting Again | ROCK |
| The Second Time | ROCK |
| Fight Story | ROCK |
+-----------------+-----------*/
執行計畫如下所示:

distributed union 運算子會將子計畫傳送至遠端伺服器,跨分割執行資料表掃描,以滿足查詢的述詞 WHERE s.SingerId = 2 AND s.SongGenre = 'ROCK'。serialize result 運算子會從資料表掃描傳回的資料列運算 SongName 和 SongGenre 值。接著,distributed union 運算子便會傳回遠端伺服器的綜合結果,做為 SQL 查詢結果。
屬性和執行作業統計資料
運算子的屬性會說明運算子執行時使用的特徵。執行統計資料是在查詢執行期間收集的值,可協助您評估運算子的效能。
Distributed union 運算子有其他不同的執行統計資料。屬性
| 名稱 | 說明 |
|---|---|
| 執行方法 | 在列執行中,運算子一次處理一列。 在批次執行中,運算子會一次處理一批資料列。 |
執行作業統計資料
| 名稱 | 說明 |
|---|---|
| 本機平行執行作業 | 並行執行的子查詢數量。 |
| 遠端呼叫 | 執行的遠端子查詢數量。 |
| 延遲時間 | 運算子中所有執行作業的經過時間。 |
| 累計延遲時間 | 目前運算子及其後代的總時間。 |
| CPU 作業時間 | 執行運算子所耗費的 CPU 作業時間總和。 |
| 累計 CPU 作業時間 | 執行運算子及其後代所花費的 CPU 作業時間總計。 |
| 執行時間 | 執行查詢及處理結果所花費的總時間。 |
| 傳回的資料列數 | 這個運算子輸出的資料列數 |
| 執行作業數量 | 運算子的執行次數。部分執行作業可以平行執行。 |
一般來說,執行作業會並行進行,與 cross apply 執行作業不同。因此,分散式運算子的延遲時間是累計的,不像大多數運算子會回報該運算子增加的延遲時間。分散式聯集下的執行次數取決於資料表的分割界限,而分割界限則取決於資料大小和負載,且可能包含 use_additional_parallelism 陳述式提示。這種統計資料做法適用於所有分散式運算子。
Distributed apply
「distributed apply」 (DA) 運算子會跨多個伺服器執行,延伸 apply join 運算子。輸入端會將資料列分組為「批次」 (與一次只能處理一個輸入列的一般 cross apply 運算子不同)。DA 對應端是執行遠端伺服器的純套用聯結運算子組。Distributed apply join 支援與 apply join 相同的 apply 方法。
屬性和執行作業統計資料
運算子的屬性會說明運算子執行時使用的特徵。執行統計資料是在查詢執行期間收集的值,可協助您評估運算子的效能。
「Distributed apply」運算子有額外的執行統計資料。屬性
| 名稱 | 說明 |
|---|---|
| 執行方法 | 在列執行中,運算子一次處理一列。 在批次執行中,運算子會一次處理一批資料列。 |
執行作業統計資料
| 名稱 | 說明 |
|---|---|
| 本機平行執行作業 | 並行執行的子查詢數量。 |
| 遠端呼叫 | 執行的遠端子查詢數量。 |
| 批次數量 | 批次是動態資料列集合,會同時處理。這會顯示從輸入端傳送至對應端的批次數量。 |
| 延遲時間 | 運算子中所有執行作業的經過時間。 |
| 累計延遲時間 | 目前運算子及其後代的總時間。 |
| CPU 作業時間 | 執行運算子所耗費的 CPU 作業時間總和。 |
| 累計 CPU 作業時間 | 執行運算子及其後代所花費的 CPU 作業時間總計。 |
| 執行時間 | 執行查詢及處理結果所花費的總時間。 |
| 傳回的資料列數 | 這個運算子輸出的資料列數 |
| 執行作業數量 | 運算子的執行次數。部分執行作業可以平行執行。 |
Distributed cross apply
下列查詢會示範這個運算子:
SELECT albumtitle
FROM songs
JOIN albums
ON albums.albumid = songs.albumid;
/*-----------------------+
| AlbumTitle |
+-----------------------+
| Green |
| Nothing To Do With Me |
| Play |
| Total Junk |
| Green |
+-----------------------*/
執行計畫如下所示:

DCA 輸入包含在 SongsBySingerAlbumSongNameDesc 索引上進行索引掃描,這項掃描會將 AlbumId 的資料列分批。DCA 的對應端是標準的交叉套用,其中輸入是一批資料列,而對應端是對 AlbumsByAlbumTitle 索引的索引掃描,受制於輸入列中符合 AlbumsByAlbumTitle 索引 AlbumId 鍵的 AlbumId 述詞。對應會在分批的輸入列中傳回 SingerId 值的 SongName。
總結此範例的 DCA 程序,DCA 的輸入是 Albums 資料表中分批的列,而 DCA 的輸出就是這些資料列應用到索引掃描的對應。
Distributed outer apply
分散式 outer apply 是指具有 left outer join 語意的 DA。如要瞭解語意,請參閱「外部套用」。
下列查詢會示範這個運算子:
SELECT lastname,
concertdate
FROM singers LEFT OUTER join@{JOIN_TYPE=APPLY_JOIN} concerts
ON singers.singerid=concerts.singerid;
/*----------+-------------+
| LastName | ConcertDate |
+----------+-------------+
| Trentor | 2014-02-18 |
| Smith | 2011-09-03 |
| Smith | 2010-06-06 |
| Lomond | 2005-04-30 |
| Martin | 2015-11-04 |
| Richards | |
+----------+-------------*/
執行計畫如下所示:

Distributed semi apply
分散式半聯結套用是具有半聯結語意的 DA。如要瞭解語意相關詳情,請參閱半套用。
Distributed anti-semi apply
分散式反半聯結套用是具有反半聯結語意的 DA。如要瞭解語意相關詳細資訊,請參閱反半形應用程式。
Distributed merge union
「distributed merge union」運算子會將查詢分配到多個遠端伺服器。然後合併查詢結果,產生排序結果,也就是分散式合併排序。
分散式合併聯集會執行下列步驟:
根伺服器會將子查詢傳送至每個遠端伺服器,這些伺服器會代管所查詢資料的分割。子查詢包含的指令會依特定順序排序結果。
每個遠端伺服器都會對分割資料執行子查詢,然後以要求的順序傳回結果。
根伺服器會合併排序後的子查詢,產生完全排序的結果。
Spanner 3 以上版本預設會啟用分散式合併聯集。
屬性和執行作業統計資料
運算子的屬性會說明運算子執行時使用的特徵。執行統計資料是在查詢執行期間收集的值,可協助您評估運算子的效能。
「Distributed apply」運算子有額外的執行統計資料。屬性
| 名稱 | 說明 |
|---|---|
| 執行方法 | 在列執行中,運算子一次處理一列。 在批次執行中,運算子會一次處理一批資料列。 |
執行作業統計資料
| 名稱 | 說明 |
|---|---|
| 本機平行執行作業 | 並行執行的子查詢數量。 |
| 遠端呼叫 | 執行的遠端子查詢數量。 |
| 批次數量 | 批次是動態資料列集合,會同時處理。這會顯示從輸入端傳送至對應端的批次數量。 |
| 延遲時間 | 運算子中所有執行作業的經過時間。 |
| 累計延遲時間 | 目前運算子及其後代的總時間。 |
| CPU 作業時間 | 執行運算子所耗費的 CPU 作業時間總和。 |
| 累計 CPU 作業時間 | 執行運算子及其後代所花費的 CPU 作業時間總計。 |
| 執行時間 | 執行查詢及處理結果所花費的總時間。 |
| 傳回的資料列數 | 這個運算子輸出的資料列數 |
| 執行作業數量 | 運算子的執行次數。部分執行作業可以平行執行。 |
推送廣播雜湊聯結
「push broadcast hash join」運算子是 SQL join 的分散式雜湊聯結實作。push broadcast hash join 運算子會從輸入端讀取資料列,以建構批次資料。運算子會將該批次廣播至包含對應端資料的所有伺服器。在接收批次資料的目的地伺服器上,運算子會使用批次資料做為建構端資料,並掃描本機資料做為雜湊聯結的探查端,藉此建構雜湊聯結。
推送廣播雜湊聯結具有下列優點:
- 如果建構資料表很小,可以傳送至所有地圖側邊分割。
- 無論是否套用剩餘的篩選器,都可以掃描地圖側邊表格。如果聯結鍵與對應資料表的主鍵不同,就會發生這種情況。
最佳化工具不會自動選取 Push broadcast hash join。如要使用這個運算子,請在查詢提示中將聯結方法設為 PUSH_BROADCAST_HASH_JOIN,如下列範例所示:
SELECT a.albumtitle,
s.songname
FROM albums AS a join@{join_method=push_broadcast_hash_join} songs AS s
ON a.singerid = s.singerid
AND a.albumid = s.albumid;
/*-----------------------+--------------------------+
| AlbumTitle | SongName |
+-----------------------+--------------------------+
| Green | The Second Time |
| Green | Starting Again |
| Green | Nothing Is The Same |
| Green | Let's Get Back Together |
| Green | I Knew You Were Magic |
| Green | Blue |
| Green | 42 |
| Terrified | Fight Story |
| Nothing To Do With Me | Not About The Guitar |
+-----------------------+--------------------------*/
執行計畫如下所示:

Push 廣播雜湊聯結的輸入內容為 AlbumsByAlbumTitle 索引。運算子會將該輸入內容序列化為一批資料。運算子會將該批次傳送至索引 SongsBySingerAlbumSongNameDesc 的所有本機分割,運算子會在其中將批次還原序列化,並建構至雜湊表。雜湊表隨後會使用本機索引資料做為探查,傳回相符結果。
相符的結果在傳回前,可能會由剩餘條件篩選。(剩餘條件出現的位置可能會在非相等的聯結)。
屬性和執行作業統計資料
運算子的屬性會說明運算子執行時使用的特徵。執行統計資料是在查詢執行期間收集的值,可協助您評估運算子的效能。
「Distributed apply」運算子有額外的執行統計資料。屬性
| 名稱 | 說明 |
|---|---|
| 執行方法 | 在列執行中,運算子一次處理一列。 在批次執行中,運算子會一次處理一批資料列。 |
執行作業統計資料
| 名稱 | 說明 |
|---|---|
| 本機平行執行作業 | 並行執行的子查詢數量。 |
| 遠端呼叫 | 執行的遠端子查詢數量。 |
| 批次數量 | 批次是動態資料列集合,會同時處理。這會顯示從輸入端傳送至對應端的批次數量。 |
| 延遲時間 | 運算子中所有執行作業的經過時間。 |
| 累計延遲時間 | 目前運算子及其後代的總時間。 |
| CPU 作業時間 | 執行運算子所耗費的 CPU 作業時間總和。 |
| 累計 CPU 作業時間 | 執行運算子及其後代所花費的 CPU 作業時間總計。 |
| 執行時間 | 執行查詢及處理結果所花費的總時間。 |
| 傳回的資料列數 | 這個運算子輸出的資料列數 |
| 執行作業數量 | 運算子的執行次數。部分執行作業可以平行執行。 |