Operator biner memiliki dua turunan relasional. Operator berikut adalah operator biner:
Skema database
Kueri dan rencana eksekusi di halaman ini didasarkan pada skema database berikut:
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);
Anda dapat menggunakan pernyataan Bahasa Manipulasi Data (DML) berikut untuk menambahkan data ke tabel ini:
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");
Gabungkan penerapan
apply join adalah operator gabungan utama yang digunakan oleh Spanner. Operator apply join menjalankan pemrosesan berorientasi baris, tidak seperti operator yang menjalankan pemrosesan berbasis set seperti hash join. Operator apply memiliki dua input, input (turunan kiri) dan map (turunan kanan). Operator apply menerapkan setiap baris di sisi input ke sisi peta menggunakan metode penerapan: cross, outer, semi, atau anti-semi. Selain itu, varian apply join juga muncul di sisi peta Distributed apply.
Operator gabungan Terapkan paling efisien jika:
- Kardinalitas input rendah.
- Kunci gabungan adalah awalan kunci utama sisi peta.
- Kueri menggabungkan dua tabel yang saling terkait.
Properti dan statistik eksekusi
Properti operator menjelaskan sifat yang digunakan saat operator dijalankan. Statistik eksekusi adalah nilai yang dikumpulkan selama eksekusi kueri untuk membantu Anda menilai performa operator.
Properti
| Nama | Deskripsi |
|---|---|
| Metode eksekusi | Dalam Eksekusi baris, operator memproses satu baris dalam satu waktu. Dalam Eksekusi batch, operator memproses batch baris sekaligus. |
Statistik eksekusi
| Nama | Deskripsi |
|---|---|
| Latensi | Waktu berlalu dari semua eksekusi yang dilakukan di operator. |
| Latensi kumulatif | Total waktu operator saat ini dan turunannya. |
| Waktu CPU | Jumlah waktu CPU yang dihabiskan untuk mengeksekusi operator. |
| Waktu CPU kumulatif | Total waktu CPU yang dihabiskan untuk mengeksekusi operator dan turunannya. |
| Waktu eksekusi | Total waktu yang diperlukan untuk menjalankan kueri dan memproses hasil. |
| Baris yang ditampilkan | Jumlah baris yang dihasilkan oleh operator ini |
| Jumlah eksekusi | Frekuensi operator dieksekusi. Beberapa eksekusi dapat berjalan secara paralel. |
Terapkan silang
Cross apply melakukan inner join yang hanya menampilkan baris yang cocok.
Kueri berikut menunjukkan operator ini:
Kueri meminta nama depan setiap penyanyi, beserta nama hanya salah satu lagu penyanyi tersebut.
SELECT si.firstname,
(SELECT so.songname
FROM songs AS so
WHERE so.singerid = si.singerid
LIMIT 1)
FROM singers AS si;
/*-----------+--------------------------+
| FirstName | Unspecified |
+-----------+--------------------------+
| Alice | Not About The Guitar |
| Catalina | Let's Get Back Together |
| David | NULL |
| Lea | NULL |
| Marc | NULL |
+-----------+--------------------------*/
Kueri ini mengisi kolom pertama dari tabel Singers, dan kolom kedua dari tabel Songs. Jika SingerId ada dalam tabel
Singers, tetapi tidak ada SingerId yang cocok dalam tabel Songs, kolom
kedua berisi NULL.
Rencana eksekusi dimulai sebagai berikut:

Node tingkat teratas adalah operator gabungan terdistribusi. Operator gabungan terdistribusi mendistribusikan sub-paket ke server jarak jauh. Subplan berisi operator serialize result yang menghitung nama depan penyanyi dan nama salah satu lagu penyanyi, serta menserialkan setiap baris output.
Operator hasil serialisasi menerima inputnya dari operator cross apply.
Sisi input untuk operator penerapan silang adalah
pemindaian tabel di tabel
Singers.
Rencana pelaksanaan dilanjutkan sebagai berikut:

Sisi peta untuk operasi lintas penerapan berisi hal berikut (dari atas ke bawah):
- Operator gabungan yang
menampilkan
Songs.SongName. - Operator limit yang membatasi jumlah lagu yang ditampilkan menjadi satu per penyanyi.
- Pemindaian indeks pada indeks
SongsBySingerAlbumSongNameDesc.
Operator penerapan silang memetakan setiap baris dari sisi input ke baris di sisi peta yang memiliki SingerId yang sama. Output operator cross apply adalah nilai
FirstName dari baris input, dan nilai SongName dari baris peta.
(Nilai SongName adalah NULL jika tidak ada baris peta yang cocok dengan
SingerId.) Operator gabungan terdistribusi di bagian atas rencana eksekusi
kemudian menggabungkan semua baris output dari server jarak jauh dan menampilkannya sebagai
hasil kueri.
Penerapan luar
Outer apply memberikan semantik left outer join. Operator ini memastikan bahwa setiap eksekusi di sisi peta menampilkan setidaknya satu baris dengan menambahkan padding NULL jika diperlukan.
Semi apply
Operator semi apply menampilkan kolom input hanya jika terjadi kecocokan di sisi peta.
Kueri berikut menggunakan semi-join untuk menemukan penyanyi yang memiliki Album:
SELECT
FirstName,
LastName
FROM
Singers
WHERE
SingerId IN (
SELECT
SingerId
FROM
Albums);
/*-----------+----------+
| FirstName | LastName |
+-----------+----------+
| Marc | Richards |
| Catalina | Smith |
| Alice | Trentor |
| Lea | Martin |
+-----------+----------*/
Segmen rencana akan muncul sebagai berikut:

Anti-semi apply
Operator Anti-semi apply mirip dengan operator semi apply, kecuali operator ini menampilkan kolom tabel input hanya jika tidak ada kecocokan di sisi peta.
Kueri berikut menggunakan anti-semi join untuk menemukan penyanyi yang tidak memiliki Album:
SELECT
FirstName,
LastName
FROM
Singers
WHERE
SingerId NOT IN (
SELECT
SingerId
FROM
Albums);
/*-----------+----------+
| FirstName | LastName |
+-----------+----------+
| David | Lomond |
+-----------+----------*/
Segmen rencana akan muncul sebagai berikut:

Gabungan hash
Operator hash join adalah implementasi berbasis hash dari gabungan SQL. Gabungan hash mengeksekusi pemrosesan berbasis set. Operator hash join membaca baris dari input yang ditandai sebagai build (turunan kiri) dan memasukkannya ke dalam tabel hash berdasarkan kondisi gabungan. Operator hash join kemudian membaca baris dari input yang ditandai sebagai probe (turunan kanan). Untuk setiap baris yang dibaca dari input probe, operator hash join akan mencari baris yang cocok dalam tabel hash. Operator hash join menampilkan baris yang cocok sebagai hasilnya.
Hash join memiliki keuntungan berikut:
- Tidak memerlukan input untuk diurutkan
- Fungsi ini menghitung filter bloom saat membuat tabel hash. Operator menggunakan filter untuk mengecualikan baris dari sisi pemeriksaan yang tidak memiliki kecocokan. Perhatikan bahwa ini adalah filter residual, bukan filter pencarian.
Kueri berikut menunjukkan operator ini:
SELECT a.albumtitle,
s.songname
FROM albums AS a join@{join_method=hash_join} songs AS s
ON a.singerid = s.singerid
AND a.albumid = s.albumid;
/*-----------------------+--------------------------+
| AlbumTitle | SongName |
+-----------------------+--------------------------+
| Nothing To Do With Me | Not About The Guitar |
| 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 |
+-----------------------+--------------------------*/
Segmen rencana eksekusi akan muncul sebagai berikut:

Dalam rencana eksekusi, build adalah gabungan terdistribusi yang
mendistribusikan pemindaian pada tabel Albums. Probe adalah operator gabungan terdistribusi
yang mendistribusikan pemindaian pada indeks SongsBySingerAlbumSongNameDesc.
Operator hash join membaca semua baris dari sisi build. Setiap baris build ditempatkan dalam tabel hash berdasarkan kolom dalam kondisi a.SingerId =
s.SingerId AND a.AlbumId = s.AlbumId. Selanjutnya, operator hash join membaca semua
baris dari sisi probe. Untuk setiap baris probe, operator hash join mencari kecocokan dalam tabel hash. Hasil kecocokan ditampilkan oleh operator gabungan hash.
Kecocokan yang dihasilkan dalam tabel hash juga dapat difilter menurut kondisi sisa sebelum ditampilkan. (Contoh kondisi residual muncul dalam gabungan non-persamaan). Rencana eksekusi gabungan hash dapat menjadi rumit karena pengelolaan memori dan varian gabungan. Algoritma gabungan hash utama diadaptasi untuk menangani varian gabungan dalam, semi, anti, dan luar.
Properti dan statistik eksekusi
Properti operator menjelaskan sifat yang digunakan saat operator dijalankan. Statistik eksekusi adalah nilai yang dikumpulkan selama eksekusi kueri untuk membantu Anda menilai performa operator.
Properti
| Nama | Deskripsi |
|---|---|
| Metode eksekusi | Dalam Eksekusi baris, operator memproses satu baris dalam satu waktu. Dalam Eksekusi batch, operator memproses batch baris sekaligus. |
Statistik eksekusi
| Nama | Deskripsi |
|---|---|
| Latensi | Waktu berlalu dari semua eksekusi yang dilakukan di operator. |
| Latensi kumulatif | Total waktu operator saat ini dan turunannya. |
| Waktu CPU | Jumlah waktu CPU yang dihabiskan untuk mengeksekusi operator. |
| Waktu CPU kumulatif | Total waktu CPU yang dihabiskan untuk mengeksekusi operator dan turunannya. |
| Waktu eksekusi | Total waktu yang diperlukan untuk menjalankan kueri dan memproses hasil. |
| Baris yang ditampilkan | Jumlah baris yang dihasilkan oleh operator ini |
| Jumlah eksekusi | Frekuensi operator dieksekusi. Beberapa eksekusi dapat berjalan secara paralel. |
Gabungkan gabungan
Operator gabungan penggabungan adalah implementasi berbasis penggabungan dari gabungan SQL. Kedua sisi
join menghasilkan baris yang diurutkan berdasarkan kolom yang digunakan dalam kondisi join. Penggabungan gabung menggunakan kedua aliran input secara bersamaan dan menghasilkan baris saat kondisi gabung terpenuhi. Jika input tidak diurutkan, pengoptimal akan menambahkan
operator Sort eksplisit ke rencana.
Penggabungan gabung memiliki keuntungan berikut:
- Jika data sudah diurutkan, tidak diperlukan memori.
- Meskipun data tidak diurutkan, untuk gabungan terdistribusi, data dapat melakukan pengurutan pada setiap pemisahan individual, bukan membuat tabel hash besar di root.
Gabungan penggabungan tidak dipilih secara otomatis oleh pengoptimal. Untuk menggunakan operator ini, tetapkan metode gabungan ke MERGE_JOIN pada petunjuk kueri, seperti yang ditunjukkan dalam contoh berikut:
SELECT a.albumtitle,
s.songname
FROM albums AS a join@{join_method=merge_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 |
+-----------------------+--------------------------*/
Rencana eksekusi akan muncul sebagai berikut:

Dalam rencana eksekusi ini, gabungan penggabungan didistribusikan sehingga gabungan dieksekusi di tempat data berada. Hal ini juga memungkinkan penggabungan gabung dalam contoh ini beroperasi
tanpa operator pengurutan tambahan, karena kedua pemindaian tabel sudah diurutkan
berdasarkan SingerId, AlbumId, yang merupakan kondisi gabung. Dalam rencana ini, pemindaian
kiri tabel Albums akan maju setiap kali SingerId, AlbumId kurang
dari nilai SingerId_1, AlbumId_1 pemindaian kanan. Demikian pula, pemindaian kanan akan maju setiap kali nilainya kurang dari nilai pemindaian kiri. Penggabungan
maju ini terus menelusuri kesetaraan untuk menampilkan baris yang cocok.
Pertimbangkan contoh penggabungan gabung lain menggunakan kueri berikut:
SELECT a.albumtitle,
s.songname
FROM albums AS a join@{join_method=merge_join} songs AS s
ON a.albumid = s.albumid;
/*-----------------------+--------------------------+
| AlbumTitle | SongName |
+-----------------------+--------------------------+
| Total Junk | The Second Time |
| Total Junk | Starting Again |
| Total Junk | Nothing Is The Same |
| Total Junk | Let's Get Back Together |
| Total Junk | I Knew You Were Magic |
| Total Junk | Blue |
| Total Junk | 42 |
| Total Junk | Not About The Guitar |
| 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 |
| Green | Not About The Guitar |
| Nothing To Do With Me | The Second Time |
| Nothing To Do With Me | Starting Again |
| Nothing To Do With Me | Nothing Is The Same |
| Nothing To Do With Me | Let's Get Back Together |
| Nothing To Do With Me | I Knew You Were Magic |
| Nothing To Do With Me | Blue |
| Nothing To Do With Me | 42 |
| Nothing To Do With Me | Not About The Guitar |
| Play | The Second Time |
| Play | Starting Again |
| Play | Nothing Is The Same |
| Play | Let's Get Back Together |
| Play | I Knew You Were Magic |
| Play | Blue |
| Play | 42 |
| Play | Not About The Guitar |
| Terrified | Fight Story |
+-----------------------+--------------------------*/
Rencana eksekusi akan muncul sebagai berikut:

Dalam rencana eksekusi sebelumnya, pengoptimal kueri memperkenalkan operator pengurutan tambahan untuk mengeksekusi gabungan penggabungan. Kondisi JOIN dalam kueri contoh ini
hanya ada di AlbumId, yang bukan cara data disimpan, sehingga pengurutan harus
ditambahkan. Mesin kueri mendukung algoritma Penggabungan Terdistribusi, yang memungkinkan pengurutan terjadi secara lokal, bukan global, sehingga mendistribusikan dan memparalelkan biaya CPU.
Kecocokan yang dihasilkan juga dapat difilter berdasarkan kondisi residual. Misalnya, kondisi residual muncul dalam gabungan non-persamaan. Rencana eksekusi gabungan penggabungan dapat menjadi rumit karena persyaratan pengurutan tambahan. Algoritma penggabungan gabungan utama menangani varian gabungan dalam, semi, anti, dan luar.
Properti dan statistik eksekusi
Properti operator menjelaskan sifat yang digunakan saat operator dijalankan. Statistik eksekusi adalah nilai yang dikumpulkan selama eksekusi kueri untuk membantu Anda menilai performa operator.
Properti
| Nama | Deskripsi |
|---|---|
| Metode eksekusi | Dalam Eksekusi baris, operator memproses satu baris dalam satu waktu. Dalam Eksekusi batch, operator memproses batch baris sekaligus. |
Statistik eksekusi
| Nama | Deskripsi |
|---|---|
| Latensi | Waktu berlalu dari semua eksekusi yang dilakukan di operator. |
| Latensi kumulatif | Total waktu operator saat ini dan turunannya. |
| Waktu CPU | Jumlah waktu CPU yang dihabiskan untuk mengeksekusi operator. |
| Waktu CPU kumulatif | Total waktu CPU yang dihabiskan untuk mengeksekusi operator dan turunannya. |
| Waktu eksekusi | Total waktu yang diperlukan untuk menjalankan kueri dan memproses hasil. |
| Baris yang ditampilkan | Jumlah baris yang dihasilkan oleh operator ini |
| Jumlah eksekusi | Frekuensi operator dieksekusi. Beberapa eksekusi dapat berjalan secara paralel. |
Gabungan rekursif
Operator recursive union melakukan gabungan dua input, satu yang mewakili
kasus base, dan yang lainnya mewakili kasus recursive. Fungsi ini digunakan dalam
kueri grafik dengan traversal jalur yang dikuantifikasi. Input dasar diproses terlebih dahulu
dan tepat satu kali. Input rekursif diproses hingga rekursi
berakhir. Rekursi berakhir saat batas atas, jika ditentukan, tercapai, atau saat rekursi tidak menghasilkan hasil baru. Dalam contoh
berikut, tabel Collaborations ditambahkan ke skema, dan grafik properti
bernama MusicGraph dibuat.
CREATE TABLE Collaborations (
SingerId INT64 NOT NULL,
FeaturingSingerId INT64 NOT NULL,
AlbumTitle STRING(MAX) NOT NULL,
) PRIMARY KEY(SingerId, FeaturingSingerId, AlbumTitle);
CREATE OR REPLACE PROPERTY GRAPH MusicGraph
NODE TABLES(
Singers
KEY(SingerId)
LABEL Singers PROPERTIES(
BirthDate,
FirstName,
LastName,
SingerId,
SingerInfo)
)
EDGE TABLES(
Collaborations AS CollabWith
KEY(SingerId, FeaturingSingerId, AlbumTitle)
SOURCE KEY(SingerId) REFERENCES Singers(SingerId)
DESTINATION KEY(FeaturingSingerId) REFERENCES Singers(SingerId)
LABEL CollabWith PROPERTIES(
AlbumTitle,
FeaturingSingerId,
SingerId),
);
Kueri grafik berikut menemukan penyanyi yang telah berkolaborasi dengan penyanyi tertentu atau berkolaborasi dengan kolaborator tersebut.
GRAPH MusicGraph
MATCH (singer:Singers {singerId:42})-[c:CollabWith]->{1,2}(featured:Singers)
RETURN singer.SingerId AS singer, featured.SingerId AS featured

Operator recursive union memfilter tabel Singers untuk menemukan penyanyi
dengan SingerId yang diberikan. Ini adalah input dasar untuk gabungan rekursif. Input rekursif ke recursive union terdiri dari distributed cross
apply atau
operator gabungan lainnya untuk kueri lain yang berulang kali menggabungkan tabel Collaborations
dengan hasil iterasi gabungan sebelumnya. Baris dari input dasar membentuk iterasi nol.
Pada setiap iterasi, output iterasi disimpan oleh pemindaian
spul rekursif. Baris dari recursive spool scan digabungkan dengan tabel Collaborations
pada spoolscan.featuredSingerId = Collaborations.SingerId. Rekursi
berakhir saat dua iterasi selesai, karena itulah batas
atas yang ditentukan dalam kueri.
Properti dan statistik eksekusi
Properti operator menjelaskan sifat yang digunakan saat operator dijalankan. Statistik eksekusi adalah nilai yang dikumpulkan selama eksekusi kueri untuk membantu Anda menilai performa operator.
Properti
| Nama | Deskripsi |
|---|---|
| Metode eksekusi | Dalam Eksekusi baris, operator memproses satu baris dalam satu waktu. Dalam Eksekusi batch, operator memproses batch baris sekaligus. |
Statistik eksekusi
| Nama | Deskripsi |
|---|---|
| Latensi | Waktu berlalu dari semua eksekusi yang dilakukan di operator. |
| Latensi kumulatif | Total waktu operator saat ini dan turunannya. |
| Waktu CPU | Jumlah waktu CPU yang dihabiskan untuk mengeksekusi operator. |
| Waktu CPU kumulatif | Total waktu CPU yang dihabiskan untuk mengeksekusi operator dan turunannya. |
| Waktu eksekusi | Total waktu yang diperlukan untuk menjalankan kueri dan memproses hasil. |
| Baris yang ditampilkan | Jumlah baris yang dihasilkan oleh operator ini |
| Jumlah eksekusi | Frekuensi operator dieksekusi. Beberapa eksekusi dapat berjalan secara paralel. |