Tüm Ürünler
Search
Belge Merkezi

MaxCompute:Aralık kümeleme

Son Güncelleme:Oct 04, 2026

Aralık kümeleme, verileri global olarak sıralı bir düzende dağıtan yeni bir veri kümeleme yöntemidir. Bu yöntem, hash kümelemeden kaynaklanabilecek veri eğikliği sorunlarını önler. Ayrıca iki düzeyde dizin oluşturmanıza olanak tanır. Aralık kümeleme; kümeleme anahtarlarına dayalı aralık sorguları ve çoklu anahtar sorguları gibi senaryolar için uygundur. Bu konuda, MaxCompute içinde aralık kümelemenin nasıl kullanılacağı açıklanmaktadır.

Genel Bilgiler

Hash kümelemeli tabloların aşağıdaki avantajları vardır:

  • Belirli bir sütun değerine göre veri sorgulamak istediğinizde, hash algoritmasını kullanarak doğrudan ilgili hash paketini bulabilirsiniz. Bu işleme paket budama adı verilir. Paketteki veriler sıralı şekilde depolanıyorsa veriyi daha da hassas konumlandırmak için dizinlerden yararlanabilirsiniz. Böylece taranan veri miktarı azalır ve sorgu verimliliği artar.

  • İki tabloyu her tablodaki belirli bir sütuna göre birleştirirseniz ve bu sütunlardan biri hash’lenmişse shuffle adımı kaldırılabilir. Bu sayede hesaplama kaynaklarından tasarruf sağlanır.

Hash kümeleme özelliği hakkında daha fazla bilgi için bkz. Hash kümeleme.

Hash kümelemenin aşağıdaki sınırlamaları bulunur:

  • Paketleri oluşturmak için hash algoritması kullandığınızda veri eğikliği sorunları ortaya çıkabilir. Birleştirme eğikliğine benzer şekilde, veri eğikliği de hash algoritmasının doğal bir sonucudur. Girdi verileri paketler arasında eşit dağılmadığında eğiklik oluşur ve paketlerdeki veri miktarları büyük farklılıklar gösterir. Hash kümelemede her paket genellikle eşzamanlı işleme birimi olarak ele alınır. Paket boyutları arasındaki dengesizlik uzun kuyruk gecikmelerine yol açabilir.

  • Paket budama yalnızca eşitlik sorgularını destekler. Bir sütunun değerlerinin 0’dan büyük olması gibi eşitsizlik koşullarına dayalı sorgularda, aranan verinin hangi pakette bulunduğu belirlenemez. Bu durumda tüm paketlerin taranması gerekir.

  • Birden fazla kümeleme anahtarı içeren sorgularda performans iyileştirmesi yalnızca tüm kümeleme anahtarlarının kullanıldığı ve tüm sorgu koşullarının eşitlik koşulu olduğu durumlarda mümkündür.

    Örneğin, aşağıdaki ifadeyle oluşturulan tablodan veri sorgulamak istediğinizde performans ancak C1=x AND C2=y koşulu kullanıldığında artar. C1=x veya C2=y gibi tekil koşullar hash kümelemeye dayalı hızlandırma sağlamaz. Bunun nedeni, anahtarların hash değerlerinin sorgu sırasında çiftler halinde birleştirilmesidir. Anahtar hash değerleri birlikte değerlendirilmezse aranan verinin bulunduğu paket tespit edilemez ve paket budama uygulanamaz.

    CREATE TABLE T2 (C1 int, C2 int, C3 string)
       CLUSTERED BY (C1, C2)
          SORTED by (C1, C2)
           INTO 1024 BUCKETS;

MaxCompute, bu sınırlamaları aşmak için aralık kümeleme adında yeni bir veri kümeleme yöntemi sunar.

Özellik açıklaması

Aralık kümeleme, verileri kümeleme anahtarlarının tam sıralamasına göre birden çok ayrık aralığa böler. Her bir aralık bir paket olarak kabul edilir ve aşağıdaki iki koşulu da karşılaması gerekir:

  • Yinelenen değerler aynı pakette depolanır.

  • Her paketteki değer sayısı yaklaşık olarak eşittir.

Aşağıdaki örnek ifade, T adlı bir tablo oluşturur.

CREATE TABLE T (C1 int) 
    RANGE CLUSTERED BY (C1) 
    SORTED BY (c1) 
    INTO 3 BUCKETS;

C1 sütunundaki değerler şunlardır: { 1, 8, -3, 2, 4, 1, 1, 3, 8, 20, -8, 9 }.

Aralık kümeleme etkinleştirildikten sonra aşağıdaki paketler elde edilir.

  • Paket 0 : { -8, -3, 1, 1, 1 }

  • Paket 1 : { 2, 3, 4 }

  • Paket 2 : { 8, 8, 9, 20 }

Not
  • Paketlerin temsil ettiği aralıklar ayrık olabilir. Örneğin, Paket 1'in aralığı [2, 4] iken Paket 2'nin aralığı [8, 20] şeklindedir. (4, 8) aralığında herhangi bir değer bulunmaz.

  • Aralık kümelemenin amacı, aralık boyutlarını değil paket boyutlarını yaklaşık olarak eşitlemektir. Veri işleme sırasında her paket eşzamanlı işleme birimi olarak görev yapar. Paket boyutlarının eşit olması, uzun kuyruk sorunlarını önler. Ancak her aralıktaki veri dağılımı aynı olmayabilir. Bu nedenle tutarlı paket boyutları, tutarlı aralık boyutları anlamına gelmez.

Aralık kümeleme işlemi MaxCompute tarafından otomatik olarak uygulanır. Her bir aralığı manuel olarak belirtmeniz gerekmez. Büyük veri senaryolarında aralıkların manuel yapılandırılması verimli veya uygulanabilir değildir. MaxCompute verileri otomatik olarak sıralar ve örnekleme yapar, her aralığın veri dağılımına göre bir histogram oluşturur ve ardından her aralığın histogramını birleştirip hesaplar. Bu sayede MaxCompute aralık kümelemenin en iyi performansını sağlar.

Bir tablo oluştururken hem RANGE CLUSTERED BY hem de SORTED BY ifadelerini belirterek verilerin genel olarak sıralanmasını sağlayabilirsiniz. Ardından MaxCompute, genel dizin ve dosya dizini olmak üzere iki düzeyde dizinler otomatik olarak oluşturur. Aşağıdaki şekilde gösterildiği gibi bu dizinler, anahtar değerlerin hızlı bir şekilde konumlandırılmasına ve aranmasına olanak tanır.range clustering

Aralık kümelemenin, karma kümelemeye göre aşağıdaki avantajları vardır:

  • Aralık sorgularını destekler.

    Örneğin, sorgu koşulu c < 3 ise sistem, genel dizini kullanarak Paket 2 ve Paket 3'ü dışlayabilir ve ardından Paket 0 ile Paket 1'den veri sorgulayabilir. Karma kümelemede paket budaması yalnızca eşitlik sorguları için gerçekleştirilebilir.

  • Çoklu anahtar sorgularını destekler.

    Örneğin, bir tablo oluştururken RANGE CLUSTERED BY (c1, c2, c3) SORTED BY (c1, c2, c3) belirtirseniz aralık kümeleme ve veri depolama c1, c2 ve c3 sırasına göre uygulanır. Bu sayede tablo verilerini c1 = 100 AND c2 > 0 veya c1 = 100 AND c2 = 50 AND c3 < 5 gibi karmaşık koşullara göre sorgulayabilirsiniz. Bu tür bir sorgu, karma kümeleme temelinde uygulanamaz.

    Önemli

    Çoklu anahtarlara dayalı bir sorguda, sorgu koşulundaki anahtarlar sıralı olmalı ve yalnızca son anahtar bir değer aralığı belirtmek için kullanılmalıdır.

  • Aralık kümeleme, genel sıralamanın verimli bir şekilde uygulanmasını sağlar.

    Aralık kümeleme kullanılmadan önce MaxCompute, verileri genel olarak sıralamak için yalnızca bir örnek kullanabilir; bu da düşük verimlilikle sonuçlanır. Aralık kümeleme kullanıldıktan sonra her aralıktaki veri eş zamanlı olarak sıralanıp birleştirilebilir ve bu da verimliliği önemli ölçüde artırır.

Kullanım notları

Aralık kümelemenin sözdizimi, hash kümelemeye benzer. Aradaki fark, aralık kümeleme için RANGE anahtar kelimesinin ve paket sayısının isteğe bağlı olmasıdır.

Aralık kümelenmiş bir tablo oluşturun

Bir aralık kümelenmiş tablo oluşturmak için CREATE TABLE ifadesini kullanabilirsiniz. Bu ifade içinde RANGE CLUSTERED BY parametresini belirtmeniz gerekir. INTO number_of_buckets BUCKETS ve SORTED BY parametreleri ise isteğe bağlıdır. Genellikle, SORTED BY ve RANGE CLUSTERED BY için aynı değerleri belirtmenizi öneririz. Bu yaklaşım, en iyi optimizasyon etkisini elde etmenize olanak tanır.

  • Sözdizimi

    CREATE TABLE [IF NOT EXISTS] <table_name>
                 [(<col_name> data_type [comment <col_comment>], ...)]
                 [comment table_comment]
                 [PARTITIONED BY (<col_name> data_type [comment <col_comment>], ...)]
                 [RANGE CLUSTERED BY (<col_name> [, <col_name>, ...])
                 [SORTED BY (<col_name> [ASC | DESC]
                 [, <col_name> [ASC | DESC] ...])]
                 [INTO <number_of_buckets> BUCKETS]]
                 [AS select_statement]
  • Örnekler

    • Bölümlenmemiş tablo

      CREATE TABLE T1 (a string, b string, c int)
                   RANGE CLUSTERED BY (c)
                   SORTED by (c)
                   INTO 1024 BUCKETS;
    • Bölümlenmiş tablo

      CREATE TABLE T1 (a string, b string, c int)
                   PARTITIONED BY (dt int)
                   RANGE CLUSTERED BY (c)
                   SORTED by (c)
                   INTO 1024 BUCKETS;
  • Parametreler

    • RANGE CLUSTERED BY

      Aralık kümeleme için anahtarları belirtir. Bu parametreyi belirttiğinizde MaxCompute, belirlediğiniz paket sayısına göre verilerin bir veya daha fazla sütununu uygun aralıklara sıralar ve örnekler. Veri eğriliği sorunlarını ve sıcak noktaları önlemek ile eşzamanlı sorguların performansını artırmak için RANGE CLUSTERED BY içinde geniş değer aralığına sahip ve yinelenen anahtar değeri az olan sütunları belirtmenizi öneririz. Sorgu performansını optimize etmek amacıyla, sık kullanılan toplama anahtarlarını veya filtre anahtarlarını bu parametrede tanımlamanız faydalı olacaktır.

    • SORTED BY

      Bir paket içindeki alanların nasıl sıralanacağını belirtir. En iyi sorgu performansına ulaşmak için SORTED BY ve RANGE CLUSTERED BY parametrelerinde aynı değerleri kullanmanızı öneririz. SORTED BY belirtildiğinde MaxCompute otomatik olarak genel bir dizin ve dosya dizinleri oluşturur; sorguları hızlandırmak üzere bu dizinlerden yararlanır.

    • INTO number_of_buckets BUCKETS

      Hash kümelemenin aksine, INTO number_of_buckets BUCKETS aralık kümeleme için isteğe bağlıdır. Bu parametreyi belirtmezseniz MaxCompute, veri miktarına göre paket sayısını otomatik olarak belirler. Çoğu durumda, paket sayısını gerçek durumunuza göre ayarlamanızı öneririz.

      Hash kümelemeye benzer şekilde, aralık kümelemede de paket boyutuna (512 MB ila 1 GB) göre paket sayısını ayarlamanızı öneririz. Aşırı büyük tablolar için çok sayıda pakete ihtiyaç duyulabilir; ancak bir tablodaki paket sayısının 4.000'i aşmaması tavsiye edilir.

Bir tablonun hash kümeleme özelliklerini değiştirin

Bölümlendirilmiş tablolar için, aralık kümeleme özelliklerini eklemek veya kaldırmak amacıyla ALTER TABLE ifadesini çalıştırabilirsiniz.

  • Sözdizimi

    -- Change a table to a range-clustered table.
    ALTER TABLE <table_name> [RANGE CLUSTERED BY (<col_name> [, <col_name>, ...])
                             [SORTED BY (<col_name> [ASC | DESC] [, <col_name> [ASC | DESC] ...])]
                             [INTO <number_of_buckets> BUCKETS];
    -- Change a range-clustered table to a non-range-clustered table.
    ALTER TABLE <table_name> NOT CLUSTERED;
  • Kullanım notları

    • ALTER TABLE ifadesi yalnızca bölümlendirilmiş bir tablonun kümeleme özelliklerini değiştirebilir. Bölümlendirilmemiş bir tabloya kümeleme özellikleri eklendikten sonra bu özellikler değiştirilemez.

    • ALTER TABLE ifadesi yalnızca tablonun yeni bölümleri için geçerlidir; bunlar INSERT OVERWRITE ifadesi kullanılarak oluşturulan yeni bölümleri de kapsar. Yeni bölümler kümeleme özelliklerine göre depolanır. Mevcut bölümlerin depolama biçimleri değişmez.

    • ALTER TABLE ifadesi yalnızca tablonun yeni bölümleri için geçerli olduğundan, bu ifade içinde bölüm belirtemezsiniz.

ALTER TABLE ifadesi mevcut tablolar için uygundur. Aralık kümeleme özellikleri eklendikten sonra yeni bölümler bu özelliklere göre depolanır.

Tablo özelliklerini doğrulayın

Aralık kümeleme özelliğine sahip bir tablo oluşturduktan sonra, tablo özelliklerini görüntülemek için aşağıdaki ifadeyi çalıştırabilirsiniz. Aralık kümeleme özellikleri, döndürülen sonucun Extended Info bölümünde gösterilir.

DESC EXTENDED <table_name>;

Örnek çıktı:


Owner: ALIYUNxxx                | Project: xxx
  TableComment:

+----------------------------+
| CreateTime:               2018-01-15 16:05:30  |
| LastDDLTime:              2018-01-15 16:05:30  |
| LastModifiedTime:         2018-01-15 16:05:30  |
+----------------------------+
| InternalTable: YES   | Size: 0               |
+----------------------------+
| Native Columns:                                |
+----------------------------+
| Field            | Type     | Label | Comment  |
+----------------------------+
| l_orderkey       | bigint   |       |          |
| l_partkey        | bigint   |       |          |
| l_suppkey        | bigint   |       |          |
| l_linenumber     | bigint   |       |          |
| l_quantity       | double   |       |          |
| l_extendedprice  | double   |       |          |
| l_discount       | double   |       |          |
| l_tax            | double   |       |          |
| l_returnflag     | string   |       |          |
| l_linestatus     | string   |       |          |
| l_shipdate       | string   |       |          |
| l_commitdate     | string   |       |          |
| l_receiptdate    | string   |       |          |
| l_shipinstruct   | string   |       |          |
| l_shipmode       | string   |       |          |
| l_comment        | string   |       |          |
+----------------------------+
| Extended Info:                                 |
+----------------------------+
| TableID:                   xxx                 |
| IsArchived:                false               |
| PhysicalSize:              0                   |
| FileNum:                   0                   |
| ClusterType:               range               |
| BucketNum:                 1024                |
| ClusterColumns:            [l_orderkey]        |
| SortColumns:               [l_orderkey ASC]    |
+----------------------------+

Extended Info bölümünde ClusterType değeri range, BucketNum değeri 1024, ClusterColumns değeri [l_orderkey] ve SortColumns değeri [l_orderkey ASC] olarak görünür. Bu durum, tablonun Aralık Kümeleme özellikleriyle başarıyla yapılandırıldığını doğrular.

Bölümlendirilmiş bir tablo için, belirli bir bölümün kümeleme özelliklerini görüntülemek üzere aşağıdaki ifadeyi de çalıştırabilirsiniz.

DESC EXTENDED <table_name> partition(<pt_spec>);

Çıktıda yer alan ClusterType, BucketNum, ClusterColumns ve SortColumns olmak üzere dört nitelik, ilgili bölümün Aralık Kümeleme yapılandırmasını belirtir.


odps@ tpch_100g>desc extended xndai_test_range partition(pt="20180115");

| PartitionSize: 0

| CreateTime:               2018-01-15 16:31:10
| LastDDLTime:              2018-01-15 16:31:10
| LastModifiedTime:         2018-01-15 16:31:10

| IsExstore:          false
| IsArchived:         false
| PhysicalSize:       0
| FileNum:            0
| ClusterType:        range
| BucketNum:          1024
| ClusterColumns:     [c1]
| SortColumns:        [c1 ASC]

Senaryolar

Filtreleme ile sorgu optimizasyonu

Bir tablo için aralık kümelemesi etkinleştirildiğinde, tablodaki veriler genel olarak sıralanır. MaxCompute, sıralanan verilere dayanarak otomatik olarak bir genel dizin ve dosya dizinleri oluşturur. Bu durum, veri depolama özelliklerine göre veri filtreleme verimliliğini artırır. Eşitlik sorgularını ve aralık sorgularını optimize etmek için aralık kümelemesini kullanabilirsiniz.

Örneğin, basit bir sorgu koşulu olan id < 3 için sistem, koşulu iyileştiriciden ayıklar ve bu koşulu (-∞, 3) değer aralığına dönüştürür. Bu durumda, sistem önceden belirtilen değer aralığında olmayan verileri içeren Hem Paket 2 hem de Paket 3'ü dışlamak için paket budama amacıyla genel dizini kullanabilir. Ardından, sistem Paket 0 ve Paket 1'deki her dosyanın dizinini kullanarak verilere hızla ulaşabilir. Aşağıdaki şekilde gösterilen bu sürece yüklem aşağı itme adı verilir.过滤查询优化 Aşağıdaki örnek ifade, veri kümesinde aralık kümelemesi gerçekleştirildikten sonra 100 GB'lık bir veri kümesinden veri sorgulamak için kullanılan bir TPC-H Sorgu 6 ifadesidir. Bir TPC-H Sorgu 6 ifadesinde, aralık filtrelemeye dayalı bir toplama işlemi gerçekleştirilir. Aralık kümelemesi, iki düzeydeki dizinleri kullanarak verilere hızla ulaşabilir. Bu sayede, sorgu yürütme süresi ve tüketilen CPU ve bellek kaynakları önemli ölçüde azalır.

select sum(l_extendedprice * l_discount) as revenue
  from tpch_lineitem l
 where l_shipdate >= '1994-01-01'
   and l_shipdate < '1995-01-01'
   and l_discount >= 0.05
   and l_discount <= 0.07
   and l_quantity < 24;

Çoklu anahtar sorguları

Bu örnekte, mf_tab tablosunu aralığa dayalı kümelenmiş (range-clustered) bir tabloya dönüştürmek için aşağıdaki ifade kullanılır. Bu yaklaşım, çoklu anahtar sorgularını daha iyi anlamanıza yardımcı olur.

ALTER TABLE mf_project.mf_tab 
            RANGE CLUSTERED BY (project_name, name)
            SORTED BY (project_name, name)
            INTO 1024 BUCKETS;

Tablo aralığa dayalı kümelenmiş bir tabloya dönüştürüldükten sonra proje düzeyinde toplu sorgular gerçekleştirebilirsiniz. Örnek ifade:

SELECT COUNT(*)
  from mf_project.mf_tab
 WHERE project_name="xxxdw"
   AND ds="20180115"
   AND type="TABLE";

Bir tabloyu kesin olarak konumlandırmak için birden fazla anahtar da kullanabilirsiniz. Örnek ifade:

SELECT count(*)
  from mf_project.mf_tab
 WHERE project_name="xxxdw"
   AND name="adm_ctu_cle_kba_midun_trade_dd"
   AND type="TABLE";

Aralık sorguları için de birden fazla anahtar kullanmanız mümkündür. Aşağıdaki ifade, adları adm ile başlayan tabloları sorgular.

SELECT count(*)
  from mf_project.mf_tab
 WHERE project_name="xxxdw"
   AND name>="adm"
   AND name < "adn"
   AND type="TABLE";

Yukarıdaki tüm sorgular, aralığa dayalı kümelemenin genel sıralama özelliğinden tam yararlanabilir ve yüklem itme (predicate pushdown) gerçekleştirerek tablo taraması için gereken G/Ç işlemlerini azaltır. Böylece veri filtreleme ve hesaplama sırasında tüketilen CPU ve bellek kaynaklarından tasarruf edilir.

Aralığa dayalı kümelemede birden fazla anahtar kullanılıyorsa belirli gereksinimlerin karşılanması gerekir. Bir tablo oluşturma ifadesindeki RANGE CLUSTERED BY k0, k1, ..., kn yapısında, veri sorgulamak için km kullanılıyorsa k0, k1, ..., km-1 anahtarlarının tümü koşullarda belirtilmeli ve bu koşulların tamamı eşitlik koşulu olmalıdır. Bu sayede dizin tabanlı sorgu hızlandırmanın en iyi performansı elde edilir.

Örneğin, T adlı bir tablodaki k1, k2 sütunları küme anahtarlarıdır.

  • Sorgu koşulu k1 < 5 ise dizin tabanlı sorgu hızlandırması sağlanabilir.

  • Sorgu koşulu k1 = 10 AND k2 = 20 ise dizin tabanlı sorgu hızlandırması sağlanabilir.

  • Sorgu koşulu k1 = 10 AND k2 < 0 ise dizin tabanlı sorgu hızlandırması sağlanabilir.

  • Sorgu koşulu k2 < 0 ise dizin tabanlı sorgu hızlandırması sağlanamaz. Bunun nedeni, sorgu koşulunda k1 değerinin belirtilmemiş olmasıdır.

  • Sorgu koşulu k1 < 0 AND k2 > 0 ise k1 < 0 koşulunu sağlayan veriler için dizin tabanlı hızlandırma kullanılabilir; k2 > 0 koşulunu sağlayan veriler için ise tablo taraması gerekir.

GROUP BY optimizasyonu

Bir tabloda aralık kümeleme etkinleştirildiğinde, tablo verileri genel olarak sıralanır. Aralık kümeleme sırasında aynı değere sahip anahtarlar aynı pakete yerleştirilir. Verilerin bu fiziksel özelliği, toplama işlemleri sırasında karıştırma (shuffle) adımını kaldırmak için kullanılabilir.

Örneğin, aşağıdaki CREATE TABLE ifadesi kullanılarak T adlı bir tablo oluşturulur. Bu tablodan veri sorgularken, GROUP BY işlemini tablo verileri üzerinde bir map aşamasında gerçekleştirebilirsiniz.

CREATE TABLE T (department int, team string, employee string)
       RANGE CLUSTERED BY (department, team)
       SORTED BY (c1, c2)
       INTO 1024 BUCKETS;

SELECT COUNT(*) from T GROUP BY department, team;
Not

GROUP BY işleminden en iyi performansı almak için GROUP BY ve RANGE CLUSTERED BY ifadelerinde aynı anahtarları belirtmeniz gerekir.

Toplama optimizasyonu

Aşağıdaki ifade, foo tablosunun veri yapısını göstermektedir.

create table foo(a bigint, b bigint, c bigint)
       range clustered by (a,b)
       sorted by(a,b) into 3 buckets;

foo tablosunun paketlerinde depolanan veriler aşağıdaki aralıklara düşer:

Bucket 0: [1,1 : 3,3]
Bucket 1: [5,5 : 7,7]
Bucket 2: [8,8 : 9,9]

Önceki paket aralıkları Bucket N: [lower bound values : upper bound values] biçiminde belirtilir. Veriler a sütununa göre toplandığında bunun yerine aşağıdaki paket aralıkları kullanılır:

Bucket 0: [1 : 3]
Bucket 1: [5 : 7]
Bucket 2: [8 : 9]

a ve b sütunlarına göre toplama işlemleri için doğrudan bir yürütme planı oluşturabilir, her paketteki verileri toplamak üzere üç örnek başlatabilir ve ardından çıkış sonucunu döndürebilirsiniz.

Ancak, a sütununun değerleri birden fazla pakete dağıldığında geçersiz bir sonuç döndürülür. Örnek:

Bucket 0: [1,1 : 3,3]
Bucket 1: [3,5 : 7,7]
Bucket 2: [7,8 : 9,9]

a sütunu, iki ayrı pakette saklanan 3 ve 7 olmak üzere iki değere sahiptir. Geçerli bir sonuç elde etmek için a sütununda aynı değere sahip demetleri aynı örneğe yerleştirmeniz ve bunları toplamanız gerekir. Bu şekilde, aşağıdaki şekilde gösterildiği gibi paketler yeniden oluşturulur. Kırmızı kesikli çizgiler arasındaki boşluk, her örneğin okuyabileceği veri aralığını belirtir.归并优化 Aralık kümelemesi için histogramlar gereklidir. Kümeleme anahtarları ve sıralama anahtarları aynı olan bir aralık kümeleme tablosunda, aralık kümeleme tablosuna veri eklediğinizde her paket için karşılık gelen çalışan, kümeleme anahtarlarının değerlerini elde etmek üzere her 10.000 satırda bir bir demet örnekleme işlemi gerçekleştirir. Elde edilen değerler bir histogramda kaydedilir. Her paketin histogramı küme meta veri dosyalarında depolanır. Bu tür histogram eş derinlikli histogram olarak adlandırılır.

Not

Demetler yalnızca kümeleme anahtarları ve sıralama anahtarları aynı olduğunda örneklenir.

Her paketin histogramı elde edildikten sonra, aşağıdaki kurallara göre her çalışan için paketleri yeniden oluşturabilirsiniz:

  • Aynı gruplama anahtarına sahip demetler aynı pakette depolanır.

  • Veriler paketlere eşit şekilde dağıtılır.

Her yeni paketin alt sınır değerlerine dayanarak, her çalışan geçerli bir aralıktaki verileri okuyabilir ve geçerli bir sonuç döndürebilir.

Aşağıdaki içerik, performans iyileştirmelerini test etmek amacıyla TPC-H veri kümesinde 1 TB veriden oluşan partsupp tablosunu kullanır. partsupp tablosunu aralığa göre kümelenmiş bir tabloya dönüştürmek için aşağıdaki deyimi çalıştırın:

CREATE TABLE partsupp ( PS_PARTKEY BIGINT NOT NULL,
                        PS_SUPPKEY BIGINT NOT NULL,
                        PS_AVAILQTY BIGINT NOT NULL,
                        PS_SUPPLYCOST  DECIMAL(15,2)  NOT NULL,
                        PS_COMMENT     VARCHAR(199) NOT NULL)
             RANGE CLUSTERED BY(PS_PARTKEY, PS_SUPPKEY)
             SORTED BY(PS_PARTKEY, PS_SUPPKEY) INTO 128 BUCKETS;

Testi gerçekleştirmek için aşağıdaki sorgu deyimini çalıştırın:

SELECT ps_partkey, count(*) c FROM partsupp GROUP BY ps_partkey;
  • Optimizasyonu devre dışı bırakmak için aşağıdaki komutu çalıştırın:

     set odps.optimizer.enable.range.partial.repartitioning=false;

    Aşağıda, optimizasyon devre dışı bırakıldığında iş çalıştırma günlüğü gösterilmektedir.

    
    resource cost: cpu 9.17 Core * Min, memory 15.15 GB * Min
    inputs:
        yuan_tpch_range_1t.partsupp: 800000000 (3376541880 bytes)
    outputs:
    Job run time: 14.000
    Job run mode: fuxi job
    Job run engine: execution engine
    M1:
        instance count: 128
        run time: 7.000
        instance time:
            min: 2.000, max: 4.000, avg: 2.000
        input records:
            TableScan1: 800000000 (min: 5496040, max: 6780663, avg: 6251772)
        output records:
            StreamLineWrite1: 200001977 (min: 1374023, max: 1695182, avg: 1562958)
        writer dumps:
            StreamLineWrite1: (min: 0, max: 0, avg: 0)
    R2_1:
        instance count: 43
        run time: 14.000
        instance time:
            min: 3.000, max: 4.000, avg: 3.000
        input records:
            StreamLineRead1: 200001977 (min: 4647288, max: 4654888, avg: 4651214)
        output records:
            AdhocSink1: 200000000 (min: 4647242, max: 4654834, avg: 4651168)
        reader dumps:
            StreamLineRead1: (min: 0, max: 0, avg: 0)
  • Optimizasyonu etkinleştirmek için aşağıdaki komutu çalıştırın:

    set odps.optimizer.enable.range.partial.repartitioning=true;

    Örnek çıktı:

    
    resource cost: cpu 4.38 Core * Min, memory 4.38 GB * Min
    inputs:
        yuan_tpch_range_1t.partsupp: 800000000 (18493328320 bytes)
    outputs:
    Job run time: 6.000
    Job run mode: fuxi job
    Job run engine: execution engine
    M1:
        instance count: 128
        run time: 6.000
        instance time:
            min: 1.000, max: 3.000, avg: 2.000
        input records:
            TableScan1: 800000000 (min: 5625876, max: 6259956, avg: 6254874)
        output records:
            AdhocSink1: 200000000 (min: 1406469, max: 1564989, avg: 1563718)

Test sonucu, optimizasyon etkinleştirildikten sonra sorgu hızının %57 arttığını, CPU kullanımının %52 azaldığını ve bellek kullanımının %71 düştüğünü göstermektedir. Performans iyileştirmeleri, veri miktarına ve sorgu türlerine bağlı olarak değişiklik gösterebilir.

Aralığa göre kümelenmiş tablolar için Join optimizasyonu

  • Bu örnekte, aşağıdaki deyimleri kullanarak iki tablo oluşturun:

    create table t1(a bigint, b bigint, c bigint, d bigint)
           range clustered by(a,b,c)
           sorted by(a,b,c) into 3 buckets;
    
    create table t2(a bigint, b bigint, c bigint, d bigint)
           range clustered by(a,b,c)
           sorted by(a,b,c) into 3 buckets;

    Ardından, bu iki tabloya farklı veriler ekleyin.

    Birleştirilmesi gereken iki hash-clustered tablonun paket sayısı aynıysa, tabloların paketlerindeki veriler doğrudan birleştirilebilir. Ancak bu kural, range-clustered tablolar için geçerli değildir. Birleştirilmesi gereken iki range-clustered tablonun paket sayısı aynı olsa bile, bu tabloların paketlerindeki veriler paket kimliklerine göre doğrudan birleştirilemez. Bunun nedeni, range-clustered bir tablodaki her paketin sınırının farklı olabilmesidir. İki range-clustered tabloyu birleştirdiğinizde, aşağıdaki şekilde gösterildiği gibi her zaman shuffle adımını içeren bir yürütme planı oluşturulur.hash clusteringİki range-clustered tablo arasındaki birleştirme işlemlerini optimize etmek için, tabloların sınırlarını hizalayarak her iki tablo için paketleri yeniden oluşturun. Bu sayede, her örnek tarafından okunabilecek verilerin sınırları yeniden tanımlanır.

  • İki tablo oluşturun.

    create table t1(a bigint, b bigint, c bigint, d bigint)
           range clustered by(a,b,c)
           sorted by(a,b,c) into 5 buckets;
    
    create table t2(a bigint, b bigint, c bigint, d bigint)
           range clustered by(a,b,c)
           sorted by(a,b,c) into 3 buckets;

    Tablolara belirli miktarda veri ekledikten sonra, aşağıdaki şekilde gösterildiği gibi paket sınırları tanımlanır.bucket boundaryÖrnek sorgu 1:

    SELECT * FROM t1 JOIN t2 ON t1.a=t2.a AND t1.b=t2.b AND t1.c=t2.c;

    Optimize edici, daha fazla pakete sahip olan tablonun sınırını diğer tablonun sınırıyla hizalar ve aşağıdaki şekilde gösterildiği gibi her tablo için yeni bir sınır belirler.bucket优化后 Bu sayede, shuffle adımını içermeyen bir yürütme planı oluşturulur.查询计划Örnek sorgu 2:

    SELECT * FROM t1 JOIN t2 ON t1.a=t2.a AND t1.b=t2.b;

    Optimize edici, her tablo için Sütun a ve Sütun b'ye dayalı olarak paketler oluşturur; ardından her tablonun her paketinden hangi verilerin okunacağını belirleyen sınırları elde etmek için paketleri hizalar ve yeniden oluşturur. Bu sayede, önceki şekilde gösterildiği gibi shuffle adımını içermeyen bir yürütme planı oluşturulur.

  • Performans testi

    • Tablo dönüşümü

      TPC-H Query 2 ifadesini kullanarak PART ve PARTSUPP adlı iki tablo üzerinde test gerçekleştirin. Her iki tablo da 1 TB veri içermektedir. Bu iki tabloyu aralığa göre kümelenmiş (range-clustered) tablolara dönüştürün, diğer tabloları ise değiştirmeden bırakın.

      CREATE TABLE PARTSUPP ( PS_PARTKEY BIGINT NOT NULL,
                              PS_SUPPKEY BIGINT NOT NULL,
                              PS_AVAILQTY BIGINT NOT NULL,
                              PS_SUPPLYCOST  DECIMAL(15,2)  NOT NULL,
                              PS_COMMENT VARCHAR(199) NOT NULL)
                   RANGE CLUSTERED BY(PS_PARTKEY, PS_SUPPKEY)
                   SORTED BY(PS_PARTKEY, PS_SUPPKEY)
                   INTO 128 BUCKETS;
      CREATE TABLE PART ( P_PARTKEY BIGINT NOT NULL,
                          P_NAME VARCHAR(55) NOT NULL,
                          P_MFGR CHAR(25) NOT NULL,
                          P_BRAND CHAR(10) NOT NULL,
                          P_TYPE  VARCHAR(25) NOT NULL,
                          P_SIZE   BIGINT NOT NULL,
                          P_CONTAINER   CHAR(10) NOT NULL,
                          P_RETAILPRICE DECIMAL(15,2) NOT NULL,
                          P_COMMENT VARCHAR(23) NOT NULL)
                   RANGE CLUSTERED BY(P_PARTKEY)
                   SORTED BY(P_PARTKEY)
                   INTO 64 BUCKETS;

      Verileri aşağıdaki TPC-H Query 2 ifadesini kullanarak sorgulayın:

      select s_acctbal,
             s_name,
             n_name,
             p_partkey,
             p_mfgr,
             s_address,
             s_phone,
             s_comment
        from part,
             supplier,
             partsupp,
             nation,
             region
       where p_partkey = ps_partkey
         and s_suppkey = ps_suppkey
         and p_size = 15
         and p_type like '%BRASS'
         and s_nationkey = n_nationkey
         and n_regionkey = r_regionkey
         and r_name = 'EUROPE'
         and ps_supplycost = (select min(ps_supplycost)
                                from partsupp, supplier, nation, region
                               where p_partkey = ps_partkey
                                 and s_suppkey = ps_suppkey
                                 and s_nationkey = n_nationkey
                                 and n_regionkey = r_regionkey
                                 and r_name = 'EUROPE')
        order by s_acctbal desc, n_name, s_name, p_partkey limit 100;
    • Test sonuçları

      • Optimizasyonu devre dışı bırakmak için aşağıdaki komutu çalıştırın:

         set odps.optimizer.enable.range.partial.repartitioning=false;

        Optimizasyon devre dışı bırakıldığında iş çalıştırma günlüğü çıktısı örneği:

        
        resource cost: cpu 61.64 Core * Min, memory 41.62 GB * Min
        inputs:
            yuan_tpch_range_1t.nation: 25 (1848 bytes)
            yuan_tpch_range_1t.partsupp: 800000000 (7392850104 bytes)
            yuan_tpch_range_1t.region: 5 (1040 bytes)
            yuan_tpch_range_1t.part: 200000000 (1427093008 bytes)
            yuan_tpch_range_1t.supplier: 10000000 (483851352 bytes)
        outputs:
            Job run time: 56.000
            Job run mode: fuxi job
            Job run engine: execution engine
            J11_13:
                instance count: 299
                run time: 52.000
                instance time:
                    min: 1.000, max: 2.000, avg: 1.000
                input records:
                    StreamLineRead13: 637969 (min: 1978, max: 2313, avg: 2133)
                    StreamLineRead7: 159971440 (min: 532818, max: 537639, avg: 535020)
                output records:
                    StreamLineWrite14: 470727 (min: 1473, max: 1676, avg: 1574)
      • Optimizasyonu etkinleştirmek için aşağıdaki komutu çalıştırın:

        set odps.optimizer.enable.range.partial.repartitioning=true;

        Örnek çıktı:

        
        resource cost: cpu 39.81 Core * Min, memory 18.89 GB * Min
        inputs:
            yuan_tpch_range_1t.nation: 25 (1848 bytes)
            yuan_tpch_range_1t.region: 5 (1040 bytes)
            yuan_tpch_range_1t.part: 200000000 (7544753176 bytes)
            yuan_tpch_range_1t.partsupp: 800000000 (22722759616 bytes)
            yuan_tpch_range_1t.supplier: 10000000 (483851352 bytes)
        outputs:
        Job run time: 44.000
        Job run mode: fuxi job
        Job run engine: execution engine
        J11_13:
            instance count: 135
            run time: 40.000
            instance time:
                min: 1.000, max: 3.000, avg: 1.000
            input records:
                StreamLineRead11: 637969 (min: 4516, max: 4962, avg: 4725)
                StreamLineRead7: 159971440 (min: 1181336, max: 1189183, avg: 1184969)
            output records:
                StreamLineWrite12: 470727 (min: 3368, max: 3647, avg: 3486)
            writer dumps:
                StreamLineWrite12: (min: 0, max: 0, avg: 0)
            reader dumps:
                StreamLineRead11: (min: 0, max: 0, avg: 0)
                StreamLineRead7: (min: 0, max: 0, avg: 0)

      Optimizasyondan sonra iki aşama kaldırılır, sorgu hızı yaklaşık %21,4 oranında artar, CPU kullanımı yaklaşık %35,4 oranında azalır ve bellek kullanımı yaklaşık %54,6 oranında düşer.

Global sıralama hızlandırma

Aralığa göre kümeleme, global sıralama hızlandırması için de kullanılabilir. ORDER BY kullanılan yaygın senaryolarda, global sıralamayı sağlamak üzere sıralanan tüm veriler aynı örneğe dağıtılır. Ancak bu senaryolarda eşzamanlı işleme tam olarak yararlanılamaz. Eşzamanlı global sıralamayı uygulamak için aralığa göre kümelemenin bölümlendirme adımını kullanabilirsiniz. Global sıralama için verileri örneklemeli, verileri aralıklara bölmeli, her bir aralıktaki verileri paralel olarak sıralamalı ve ardından global sıralama sonucunu elde etmelisiniz.

Global sıralama tamamlandıktan sonra, tablonun veya tablodaki bir bölümün küme özelliklerini değiştirdiğinizde tabloda hala birden çok paket bulunur. Veri tüketimi sırasında, global sıralamayı sağlamak üzere dosyalardaki verilerin paket kimliklerine göre okunması gerekir.

Varsayılan olarak, aralık kümeleme tabloları için genel sıralama hızlandırma özelliği devre dışı bırakılır. Genel sıralama hızlandırmayı etkinleştirmek için aşağıdaki komutu çalıştırın:

set odps.optimizer.distribute.ordering.enable=true;

Sınırlamalar ve kullanım notları

Karma kümelemeye kıyasla aralık kümelemenin aşağıdaki sınırlamaları bulunur:

  • Aralık kümelemenin veri oluşturma maliyetleri, karma kümelemeye göre daha yüksektir. Karma kümeleme yalnızca verilerin hash'lenmesi ve sıralanması gibi basit bir işlemdir. Buna karşın aralık kümeleme için veri örnekleme, sıralama ve histogram birleştirme adımları gerekir. Çalıştırma süreleri, CPU kullanımı ve bellek tüketimi dahil olmak üzere toplam kaynak tüketimi, karma kümelemeye kıyasla daha fazladır. Bu nedenle, sorunları çözmek için karma kümeleme yeterliyse aralık kümeleme kullanmanıza gerek yoktur.

  • DYNAMIC PARTITION veya INSERT INTO işlemlerinde aralık kümeleme desteklenmez.

  • Aralık kümeleme yalnızca inner join, left outer join, right outer join ve semi join işlemleri için desteklenir. Anti-join veya full outer join işlemlerinde aralık kümeleme desteklenmez.

  • Aralık kümeleme tablolarında RANGE CLUSTERED BY ifadesinde belirtilen anahtarlar, SORTED BY ifadesinde belirtilen anahtarlarla aynı olmalıdır. Örneğin, foo adlı bir tablo oluştururken range clustered by (a,b) sorted by (a,b) belirtirseniz bu konudaki optimizasyonlardan yararlanabilirsiniz. Ancak bar adlı bir tablo için range clustered by(a,b) sorted by (b,a) belirtirseniz bu konudaki optimizasyonlardan yararlanamazsınız.

  • JOIN veya GROUP BY işlemlerinde belirtilen anahtarlar, RANGE CLUSTERED BY ifadesinde belirtilen anahtarların ön eki veya tamamı olmalıdır. Örneğin, bir tablo oluşturma deyimi içinde range clustered by(a,b,c) sorted by(a,b,c) belirtildiğini varsayalım. Bu konudaki optimizasyonlardan yalnızca JOIN veya GROUP BY anahtarı olarak a, a,b veya a,b,c belirtildiğinde yararlanabilirsiniz. Anahtar olarak b veya a,c belirtildiğinde ise bu optimizasyonlardan yararlanamazsınız.

  • Bölümlendirilmiş bir aralık kümeleme tablosundan iki veya daha fazla bölüm okumak isterseniz bu konudaki optimizasyonlardan yararlanamazsınız. Bu optimizasyonlar yalnızca tek bölümlü bölümlendirilmiş tablolar ve bölümlendirilmemiş tablolar için geçerlidir.