Standart bölümlemeli tablolarla çalışırken, veri yazmadan önce her bölümü tek tek oluşturmanız ve her satır için doğru bölüm değerini manuel olarak hesaplamınız gerekir. AUTO PARTITION (Otomatik Bölümleme) tabloları bu yükü ortadan kaldırır: Tablo oluşturma aşamasında bir zaman hesaplama işlevi tanımlarsınız ve MaxCompute, veri yazılırken bu işleve dayanarak her satır için bölüm sütunu değerini otomatik olarak üretir.
Bu konu, mevcut bir tarih/saat sütununa uygulanan zaman hesaplama işlevinden türetilen bölümlere sahip otomatik bölümlemeli tabloları ele almaktadır. Bunun yerine veri yazma zamanına dayalı otomatik bölümleme hakkında bilgi edinmek için bkz. Veri yazma zamanına dayalı otomatik bölümlemeli tablolar. Tüm bölümlemeli tablo türlerine genel bir bakış için bkz. Bölümlemeli tablolara genel bakış.
Sınırlamalar
Her tabloda yalnızca bir bölüm sütunu desteklenir. Çok düzeyli bölümleme desteklenmez.
Bölüm sütunu, tablo oluşturma sırasında tanımlanan bölüm ifadesine göre otomatik olarak üretilir. Veri türü her zaman STRING'dir ve değiştirilemez.
Otomatik bölümleme yalnızca MaxCompute SQL ile veri yazılırken desteklenir. Flink bağlayıcıları gibi diğer yazma yöntemleri desteklenmez.
Otomatik bölümlemeli tablo oluşturun
Söz dizimi
CREATE [OR REPLACE] TABLE [IF NOT EXISTS] <table_name> (<col_name> <data_type>, ...)
[COMMENT <table_comment>]
AUTO PARTITIONED BY (<auto_partition_expression> [AS <auto_partition_column_name>]);
Parametreler
| Parametre | Zorunlu | Açıklama |
|---|---|---|
table_name |
Evet | Oluşturulacak tablonun adı. |
col_name |
Evet | Sütun adı. |
data_type |
Evet | Sütun veri türü. Bölüm kaynağı sütunu için desteklenen tarih/saat türleri: DATE, DATETIME, TIMESTAMP, TIMESTAMP_NTZ. |
table_comment |
Hayır | Tablo için açıklama. |
auto_partition_expression |
Evet | Bölüm sütunu değerlerinin nasıl hesaplanacağını tanımlayan ifade. Yalnızca TRUNC_TIME işlevi desteklenir. Elde edilen bölüm sütunu her zaman STRING türündedir ve değerleri doğrudan işlemleri desteklemez. |
auto_partition_column_name |
Hayır | Oluşturulan bölüm sütununun adı. Belirtilmezse sistem _pt_col_0_ kullanır ve kullanılmayan bir ad bulunana kadar son eki artırır (_pt_col_1_, _pt_col_2_ vb.). |
Örnekler
Örnek 1: TIMESTAMP sütunu kullanarak günlere göre bölümleme (varsayılan bölüm sütunu adı)
TIMESTAMP türünde sale_time sütunu içeren ve günlere göre bölümlenen sale_detail adlı otomatik bölümlemeli bir tablo oluşturun:
CREATE TABLE IF NOT EXISTS sale_detail(
shop_name STRING,
total_price DOUBLE,
sale_time TIMESTAMP)
AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day'));
Tablo dört sütun içerir: shop_name, total_price, sale_time ve _pt_col_0_. _pt_col_0_ sütunu, STRING türünde otomatik olarak oluşturulan bölüm sütunudur.
Tablo yapısını görüntülemek için DESC sale_detail; komutunu çalıştırın:
+------------------------------------------------------------------------------------+
| Owner: ALIYUN$*** |
| Project: *** |
| TableComment: |
+------------------------------------------------------------------------------------+
| CreateTime: 2025-06-26 11:21:55 |
| LastDDLTime: 2025-06-26 11:21:55 |
| LastModifiedTime: 2025-06-26 11:21:55 |
+------------------------------------------------------------------------------------+
| InternalTable: YES | Size: 0 |
+------------------------------------------------------------------------------------+
| Native Columns: |
+------------------------------------------------------------------------------------+
| Field | Type | Label | Comment |
+------------------------------------------------------------------------------------+
| shop_name | string | | |
| total_price | double | | |
| sale_time | timestamp | | |
+------------------------------------------------------------------------------------+
| Partition Columns: |
+------------------------------------------------------------------------------------+
| _pt_col_0_ | string | |
+------------------------------------------------------------------------------------+
AUTO PARTITION sütunu için bölüm oluşturma ifadesini görüntülemek üzere SHOW CREATE TABLE komutunu kullanın.
Örnek 2: Açık bir bölüm sütunu adı ile günlere göre bölümleme
Açık bir bölüm sütunu adı sale_date belirtin:
CREATE TABLE IF NOT EXISTS sale_detail2(
shop_name STRING,
total_price DOUBLE,
sale_time TIMESTAMP)
AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day') AS sale_date);
Örnek 3: DATE sütunları için basitleştirilmiş söz dizimi
Kaynak sütun DATE türündeyse ve kesme granülerliği day ise TRUNC_TIME ifadesini atlayabilirsiniz:
-- Full syntax
CREATE TABLE IF NOT EXISTS sale_detail3(
shop_name STRING,
total_price DOUBLE,
sale_date DATE)
AUTO PARTITIONED BY (TRUNC_TIME(sale_date, 'day'));
-- Simplified syntax (equivalent)
CREATE TABLE IF NOT EXISTS sale_detail3(
shop_name STRING,
total_price DOUBLE,
sale_date DATE)
AUTO PARTITIONED BY (sale_date);
Basitleştirilmiş söz dizimi yalnızca DATE türünü destekler. DATETIME, TIMESTAMP ve TIMESTAMP_NTZ desteklenmez.
Otomatik bölümlemeli tabloya veri yazın
MaxCompute SQL kullanarak veri yazdığınızda sistem, tablo oluşturma sırasında tanımlanan bölüm ifadesine göre her satır için bölüm sütunu değerini hesaplar. Bölüm değerlerini açıkça belirtemezsiniz.
Örnek: sale_detail2 tablosuna veri yazın
-- Set the project time zone to UTC+8 (Asia/Shanghai)
SET odps.sql.timezone=Asia/Shanghai;
-- Create the table (same as Example 2 above)
CREATE TABLE IF NOT EXISTS sale_detail2(
shop_name STRING,
total_price DOUBLE,
sale_time TIMESTAMP)
AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day') AS sale_date);
-- Insert data
INSERT INTO sale_detail2 VALUES
('chongqin_shop', 101101, TIMESTAMP '2025-02-04 01:15:30'),
('shenzhen_shop', 202202, TIMESTAMP '2024-03-29 15:30:30'),
('hangzhou_shop', 303303, TIMESTAMP '2025-02-04 08:30:30'),
('shanghai_shop', 404404, TIMESTAMP '2025-02-28 01:50:30');
Aşağıdaki tabloda, her sale_time değerinin TRUNC_TIME hesaplamasından sonra hangi bölüme eşlendiği gösterilmektedir:
**sale_time (Asia/Shanghai, UTC+8)** |
**Bölüm sale_date (UTC)** |
|---|---|
| 2025-02-04 01:15:30 | 2025-02-03 |
| 2024-03-29 15:30:30 | 2024-03-29 |
| 2025-02-04 08:30:30 | 2025-02-04 |
| 2025-02-28 01:50:30 | 2025-02-27 |
DATETIME ve TIMESTAMP sütunları içinTRUNC_TIMEişlevi, kesme işleminden önce yerel saati UTC'ye dönüştürür. Gece yarısına yakın yazılan satırlar, yerel tarihin önerdiğinden farklı bir bölüme atanabilir. Örneğin,2025-02-04 01:15:30(UTC+8) saati UTC'de2025-02-03 17:15:30olduğundan2025-02-04yerine2025-02-03bölümüne atanır.
Otomatik bölümlemeli tabloyu sorgulayın
**Örnek 1: SELECT * varsayılan olarak bölüm sütununu dahil etmez**
-- Enable full table scan
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail2;
-- Result
+------------+-------------+---------------------+
| shop_name | total_price | sale_time |
+------------+-------------+---------------------+
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
| shenzhen_shop | 202202.0 | 2024-03-29 15:30:30 |
| chongqin_shop | 101101.0 | 2025-02-04 01:15:30 |
+------------+-------------+---------------------+
Örnek 2: Bölüm sütununu çıktıya dahil edin
Bölüm sütununu sonuçlara dahil etmek için adına göre referans verin:
SELECT *, sale_date FROM sale_detail2;
-- Result
+------------+-------------+---------------------+------------+
| shop_name | total_price | sale_time | sale_date |
+------------+-------------+---------------------+------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 | 2025-02-27 |
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 | 2025-02-04 |
| shenzhen_shop | 202202.0 | 2024-03-29 15:30:30 | 2024-03-29 |
| chongqin_shop | 101101.0 | 2025-02-04 01:15:30 | 2025-02-03 |
+------------+-------------+---------------------+------------+
Bölüm kırpma
Bölüm kırpma, yalnızca filtre koşuluyla eşleşen bölümleri tarayarak sorgu maliyetini azaltır. Bölüm kırpmasının çalışıp çalışmadığını doğrulamak için Logview'deki SQL yürütme planını kontrol edin veya EXPLAIN komutunu kullanın. Ayrıntılar için bkz. Bölüm kırpmanın etkinliğini değerlendirme.
Otomatik bölümlemeli tablolar için üç senaryoda bölüm kırpma desteklenir.
Oluşturulan bölüm sütununda filtreleme
Doğrudan bölüm sütununda (sale_date) filtreleme yapmak bölüm kırpmayı tetikler:
SELECT * FROM sale_detail2 WHERE sale_date > '2025-02-03';
-- Result: only partitions where sale_date > '2025-02-03' are scanned
+------------+-------------+---------------------+
| shop_name | total_price | sale_time |
+------------+-------------+---------------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
+------------+-------------+---------------------+
Kaynak saat sütununda filtreleme (işlevsiz)
Kaynak saat sütununda (sale_time), onu bir işleve sarmalamadan doğrudan filtreleme yapmak da bölüm kırpmayı tetikler. Sistem filtre aralığını ilgili bölüm sınırlarına eşler:
SELECT * FROM sale_detail2 WHERE sale_time > '2025-02-04 08:00:00';
-- Result: only partitions containing matching sale_time values are scanned
+------------+-------------+---------------------+
| shop_name | total_price | sale_time |
+------------+-------------+---------------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
+------------+-------------+---------------------+
Kaynak saat sütununda işlev kullanarak filtreleme
Filtre koşulunda kaynak saat sütununa bir işlev uyguladığınızda, bölüm kırpma yalnızca işlevin kesme granülerliği tablo oluşturulurken kullanılan granülerlikle eşleşiyorsa çalışır. Bu gereklidir çünkü sistem, bir filtre koşulunu yalnızca her ikisi de zamanı aynı çözünürlükte ifade ettiğinde bölüm sınırlarına eşleyebilir.
| İşlev | Bölüm kırpma koşulu |
|---|---|
| TRUNC_TIME | Kesme granülerliği tablo oluşturma deyimiyle eşleşir |
| DATETRUNC | Kesme granülerliği tablo oluşturma deyimiyle eşleşir |
| CAST AS DATE | Tablo day granülerliği ile oluşturulmuştur |
| TO_DATE | Tablo day granülerliği ile oluşturulmuştur; saat dilimi parametresi yok |
Örnek 1: TRUNC_TIME veya DATETRUNC kullanarak filtreleme (saat dilimi parametresi olmadan)
Her iki sorgu da bölüm kırpmayı tetikler çünkü kesme granülerliği (day / dd), sale_detail2 tablosunu oluşturmak için kullanılan day granülerliğiyle eşleşir ve hiçbir işlev saat dilimi parametresiyle çağrılmaz:
SELECT * FROM sale_detail2 WHERE TRUNC_TIME(sale_time, 'day') > '2025-02-04';
SELECT * FROM sale_detail2 WHERE DATETRUNC(sale_time, 'dd') > '2025-02-04 00:00:00';
-- Result
+------------+-------------+---------------------+
| shop_name | total_price | sale_time |
+------------+-------------+---------------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
+------------+-------------+---------------------+
Örnek 2: CAST AS DATE veya TO_DATE kullanarak filtreleme (saat dilimi parametresi olmadan)
sale_detail2 tablosu day granülerliği ile oluşturulduğundan her iki sorgu da bölüm kırpmayı tetikler:
SELECT * FROM sale_detail2 WHERE CAST(sale_time AS DATE) = '2025-02-04';
SELECT * FROM sale_detail2 WHERE TO_DATE(sale_time) = '2025-02-04';
-- Result
+------------+-------------+---------------------+
| shop_name | total_price | sale_time |
+------------+-------------+---------------------+
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
+------------+-------------+---------------------+