MaxCompute mengeksekusi klausa dalam pernyataan SELECT dengan urutan yang berbeda dari tampilannya dalam sintaks tertulis. Memahami urutan eksekusi ini membantu Anda menulis logika kueri yang benar—terutama saat menggunakan GROUP BY, HAVING, serta klausa khusus MaxCompute seperti DISTRIBUTE BY dan SORT BY.
Urutan eksekusi
Sintaks SELECT mendukung klausa berikut: SELECT, FROM, WHERE, GROUP BY, HAVING, WINDOW, QUALIFY, ORDER BY, DISTRIBUTE BY, SORT BY, dan LIMIT.
MaxCompute mengeksekusi klausa-klausa tersebut dalam salah satu dari dua urutan, tergantung pada klausa yang digunakan.
ORDER BYdanGROUP BYtidak dapat digunakan bersamaan denganDISTRIBUTE BYatauSORT BY.
Urutan 1 — digunakan ketika kueri mencakup GROUP BY, ORDER BY, atau LIMIT:
-
FROM -
WHERE -
GROUP BY -
HAVING -
SELECT -
ORDER BY -
LIMIT
Urutan 2 — digunakan ketika kueri mencakup DISTRIBUTE BY atau SORT BY:
-
FROM -
WHERE -
SELECT -
DISTRIBUTE BY -
SORT BY
Meskipun SELECT muncul pertama dalam sintaks tertulis, klausa ini hanya dieksekusi setelah FROM, WHERE, GROUP BY, dan HAVING diproses.
Tulis pernyataan dalam urutan eksekusi
Untuk mempermudah pembacaan logika kueri, MaxCompute memungkinkan Anda menulis pernyataan SELECT dalam urutan eksekusi—dengan FROM di awal, bukan SELECT. Kedua bentuk ini setara:
-- Bentuk standar (SELECT pertama)
SELECT region, max(total_price)
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
ORDER BY region
LIMIT 5;
-- Bentuk urutan eksekusi (FROM pertama) — setara dengan pernyataan di atas
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
SELECT region, max(total_price)
ORDER BY region
LIMIT 5;
Sintaks lengkap dalam urutan eksekusi adalah:
FROM <table_reference>
[WHERE <where_condition>]
[GROUP BY <col_list>]
[HAVING <having_condition>]
[WINDOW <window_name> AS (<window_definition>)]
[QUALIFY <expression>]
SELECT [ALL | DISTINCT] <select_expr>, <select_expr>, ...
[ORDER BY <order_condition>]
[DISTRIBUTE BY <distribute_condition> [SORT BY <sort_condition>]]
[LIMIT <number>]
Data contoh
Contoh dalam topik ini menggunakan tabel partisi bernama sale_detail. Jalankan pernyataan berikut untuk membuat dan mengisi tabel tersebut:
-- Membuat tabel partisi bernama sale_detail
CREATE TABLE IF NOT EXISTS sale_detail
(
shop_name string,
customer_id string,
total_price double
)
PARTITIONED BY (sale_date string, region string);
-- Menambahkan partisi
ALTER TABLE sale_detail ADD
PARTITION (sale_date='2013', region='china')
PARTITION (sale_date='2014', region='shanghai');
-- Memasukkan data
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china')
VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);
INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai')
VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);
Untuk melihat seluruh isi tabel:
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;+------------+-------------+-------------+------------+------------+
| shop_name | customer_id | total_price | sale_date | region |
+------------+-------------+-------------+------------+------------+
| s1 | c1 | 100.1 | 2013 | china |
| s2 | c2 | 100.2 | 2013 | china |
| s3 | c3 | 100.3 | 2013 | china |
| null | c5 | NULL | 2014 | shanghai |
| s6 | c6 | 100.4 | 2014 | shanghai |
| s7 | c7 | 100.5 | 2014 | shanghai |
+------------+-------------+-------------+------------+------------+
Contoh
Contoh 1: Urutan 1 (GROUP BY dan ORDER BY)
Menanyakan tabel partisi tanpa menentukan partisi memerlukan pemindaian tabel penuh. Tambahkan SET odps.sql.allow.fullscan=true; sebelum pernyataan untuk mengaktifkannya.
Kedua pernyataan berikut setara dan menggunakan Urutan 1.
-- Bentuk standar
SET odps.sql.allow.fullscan=true;
SELECT region, max(total_price)
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
ORDER BY region
LIMIT 5;
-- Bentuk urutan eksekusi
SET odps.sql.allow.fullscan=true;
FROM sale_detail
WHERE total_price > 100
GROUP BY region
HAVING sum(total_price) > 300.5
SELECT region, max(total_price)
ORDER BY region
LIMIT 5;
Hasil:
+------------+------------+
| region | _c1 |
+------------+------------+
| china | 100.3 |
+------------+------------+
Cara klausa dieksekusi:
-
FROM
sale_detail— membaca baris dari tabel. -
WHERE
total_price > 100— hanya menyimpan baris yang nilaitotal_price-nya melebihi 100. -
GROUP BY
region— mengelompokkan baris yang tersisa berdasarkan wilayah. -
HAVING
sum(total_price) > 300.5— hanya menyimpan kelompok yang jumlah total harganya melebihi 300.5. -
SELECT
region, max(total_price)— memproyeksikan wilayah dan harga maksimum dari setiap kelompok. -
ORDER BY
region— mengurutkan hasil berdasarkan wilayah. -
LIMIT
5— mengembalikan lima baris pertama.
Contoh 2: Urutan 2 (DISTRIBUTE BY dan SORT BY)
Kedua pernyataan berikut setara dan menggunakan Urutan 2.
-- Bentuk standar
SET odps.sql.allow.fullscan=true;
SELECT shop_name,
total_price,
region
FROM sale_detail
WHERE total_price > 100.2
DISTRIBUTE BY region
SORT BY total_price;
-- Bentuk urutan eksekusi
SET odps.sql.allow.fullscan=true;
FROM sale_detail
WHERE total_price > 100.2
SELECT shop_name,
total_price,
region
DISTRIBUTE BY region
SORT BY total_price;
Hasil:
+------------+-------------+------------+
| shop_name | total_price | region |
+------------+-------------+------------+
| s3 | 100.3 | china |
| s6 | 100.4 | shanghai |
| s7 | 100.5 | shanghai |
+------------+-------------+------------+
Cara klausa dieksekusi:
-
FROM
sale_detail— membaca baris dari tabel. -
WHERE
total_price > 100.2— hanya menyimpan baris yang nilaitotal_price-nya melebihi 100.2. -
SELECT
shop_name, total_price, region— memproyeksikan ketiga kolom tersebut. -
DISTRIBUTE BY
region— mendistribusikan baris ke reducer menggunakan partisi hash pada kolom region. -
SORT BY
total_price— mengurutkan baris dalam setiap reducer secara menaik berdasarkantotal_price.