Veri kümeniz yüz milyonlarca satıra ulaştığında, COUNT(DISTINCT ...) yavaşlar. Tüm farklı değerler, nihai birleştirme işlemi için her düğümden tek bir üst düzey düğüme aktarılır; bu durum, veri hacmi ve bitmap boyutuyla birlikte büyüyen bir darboğaz yaratır. ApsaraDB for SelectDB, bu sorunu ortogonal bitmap kullanarak çözer: Veriler paketlere ayrılır, böylece her düğüm kendi kesişimini veya birleşimini bağımsız olarak hesaplayabilir ve yalnızca azaltılmış sonuçlar üst düzey düğüme gider.
Ortogonal Bitmap Nasıl Çalışır?
Standart COUNT(DISTINCT ...) iki aşamada çalışır:
Scan (Node 1) Scan (Node 2)
+---------+---------+ +---------+---------+
| user_id | tag | | user_id | tag |
+---------+---------+ +---------+---------+
| 1 | A | | 3 | A |
| 2 | B | | 4 | C |
+---------+---------+ +---------+---------+
| |
+----------+ +-----------+
| |
Top-level node
Receives ALL distinct values
from every node, merges them
(bottleneck: I/O + single-node compute)
Bir bitmap 1 GB'ı aştığında, bu son birleştirme adımı hem ağ G/Ç'sinde hem de tek düğüm hesaplama yükünde darboğaza neden olur.
ApsaraDB for SelectDB, bu darboğazı bir hid (hash ID) sütunu kullanarak önler. Tablo oluşturma sırasında, kullanıcı kimlikleri bir hash algoritması kullanılarak paketlere atanır. Farklı paketlerdeki bitmap değerleri ortogonaldir (örtüşmez), böylece her paket kendi sonucunu bağımsız olarak hesaplar:
Stage 1 (distributed): each bucket computes intersection/union locally
Stage 2 (merge): top-level node combines per-bucket results (small data only)
Bu yaklaşım, tek düğüm darboğazını ortadan kaldırır ve milyarlarca satıra kadar ölçeklendirilebilir.
Sınırlamalar
Başlamadan önce aşağıdaki kısıtlamaları dikkate alın:
Aggregate Key modeli gereklidir: Bitmap sütunu, Aggregate Key modelini kullanan bir tabloda bulunmalı ve toplama işlevi olarak
BITMAP_UNIONkullanılmalıdır.Bölümlendirilmiş tablolar desteklenmez: Ortogonal bitmap işlevleri bölümlendirilmiş tablolarda kullanılamaz. Bölüm sınırları, paketler arasındaki ortogonallik garantisini bozar ve sonuçların güvenilirliğini zedeler.
hidkardinalite gereksinimi: Hash paketlemesinden sonra dengeli veri dağıtımı sağlamak içinhidsütununun kardinalitesi, paket sayısının en az beş katı olmalıdır.
Bitmap Tekilleştirmeyi Ayarlama
1. Adım: Tabloyu Oluşturma
Bitmap Value alanı ve hash paketleme için bir hid sütunu içeren Aggregate Key modelini kullanarak bir tablo oluşturun.
CREATE TABLE `user_tag_bitmap` (
`tag` BIGINT(20) NULL COMMENT "User tag",
`hid` SMALLINT(6) NULL COMMENT "Bucket ID",
`user_id` BITMAP BITMAP_UNION NULL COMMENT "User bitmap"
) ENGINE=OLAP
AGGREGATE KEY(`tag`, `hid`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`hid`) BUCKETS 3;
hid sütunu, user_id aralığını gruplara böler ve her grubu tek bir pakete atar. Bu durum, paketler arasındaki bitmap değerlerinin ortogonal olmasını sağlar.
hid kardinalitesini paket sayısının en az beş katına ayarlayın. Örneğin, 3 paket varsa hid en az 15 farklı değere sahip olmalıdır.
2. Adım: Verileri İçe Aktarma
Verileri yüklemek için bir LOAD LABEL deyimi kullanın. ceil(tmp_user_id/500) ifadesi, her satır için hid değerini hesaplar ve to_bitmap(tmp_user_id) ham tamsayıyı bir bitmap girişine dönüştürür.
LOAD LABEL user_tag_bitmap_test
(
DATA INFILE('hdfs://abc')
INTO TABLE user_tag_bitmap
COLUMNS TERMINATED BY ','
(tmp_tag, tmp_user_id)
SET (
tag = tmp_tag,
hid = ceil(tmp_user_id/500),
user_id = to_bitmap(tmp_user_id)
)
)
Bölen 500 sabit değildir. Beklenen kullanıcı kimliği aralığına ve hedeflediğiniz farklı hid değeri sayısına göre bunu ayarlayın.
Kaynak veri formatı, virgülle ayrılmış iki sütundan oluşur: etiket ve kullanıcı kimliği:
11111111,1
11111112,2
11111113,3
11111114,4
İçe aktarma sırasında, SelectDB [1, 5000000) aralığındaki kullanıcı kimliklerine aynı hid değerini atar ve bunları aynı pakete yerleştirir. Paketler arasındaki bitmap değerleri ortogonal kalır, bu da kesişim ve birleşim işlemlerinin hesaplama maliyetini azaltır.
3. Adım: Ortogonal Bitmap İşlevleriyle Sorgulama
Verileri içe aktardıktan sonra, sonraki bölümde açıklanan ortogonal bitmap işlevlerini kullanın. Standart bitmap işlevlerinin tam listesi için SQL referansı konusuna bakın.
Ortogonal Bitmap İşlevleri
Aşağıdaki beş işlev, ortogonal senaryolarda bitmap sorgularını destekler. Sayı döndüren işlevler, ilgili COUNT(DISTINCT ...) kalıplarının doğrudan yerine geçer ancak dağıtık şekilde çalışır.
| İşlev | Döndürür | Ne zaman kullanılır |
|---|---|---|
bitmap_orthogonal_intersect |
Bitmap | Etiketler arasında kesişim bitmap'i hesaplarken |
orthogonal_bitmap_intersect_count |
Sayı | Birden çok etiketin kesişimindeki kullanıcıları sayarken |
orthogonal_bitmap_union_count |
Sayı | Etiketler genelindeki toplam farklı kullanıcıları sayarken |
orthogonal_bitmap_expr_calculate |
Bitmap | Karmaşık küme ifadelerini (AND, OR, NOT) değerlendirirken |
orthogonal_bitmap_expr_calculate_count |
Sayı | Karmaşık küme ifadelerinin sonuçlarını sayarken |
Ortogonal bitmap işlevleri bölümlendirilmiş tablolarda kullanılamaz. Bölümler birbirine ortogonal olduğundan, bölümler arasındaki verilerin ortogonal olması garanti edilmez ve sonuçlar güvenilir olmaz.
bitmap_orthogonal_intersect
Belirtilen filtre değerleri boyunca bitmap değerlerinin kesişimini hesaplar ve sonucu bitmap olarak döndürür.
Sözdizimi
bitmap_orthogonal_intersect(bitmap_column, column_to_filter, filter_values)
Parametreler
| Parametre | Açıklama |
|---|---|
bitmap_column |
Toplanacak bitmap sütunu. |
column_to_filter |
Filtreleme için kullanılan boyut sütunu. |
filter_values |
Boyut sütununu filtrelemek için değişken uzunlukta bir değer listesi. |
Örnek
SELECT BITMAP_COUNT(bitmap_orthogonal_intersect(user_id, tag, 13080800, 11110200))
FROM user_tag_bitmap
WHERE tag IN (13080800, 11110200);
Şuna eşdeğerdir:
-- Returns the count of users who appear in ALL specified tags
SELECT COUNT(DISTINCT user_id)
FROM user_tag_bitmap
WHERE tag IN (13080800, 11110200)
AND <user_id appears in every tag>;
Çalışma sırasında, 1. Aşama satırları belirtilen etiketlere göre filtreler ve ardından her paket için eşleşen tüm etiketler arasında bitmap kesişimini hesaplar. 2. Aşama, paket bazındaki kesişim bitmap'lerini yinelemeli olarak birleştirerek nihai sonucu oluşturur.
orthogonal_bitmap_intersect_count
Bitmap değerlerinin kesişimini hesaplar ve sayıyı doğrudan döndürür. Anlamsal olarak intersect_count ile eşleşir, ancak çalışma paketler arasında dağıtılır.Sözdizimi intersect_count işleviyle aynıdır, ancak uygulama farklıdır.Sözdizimi bitmap_union_count işleviyle aynıdır, ancak uygulama farklıdır.
Sözdizimi
orthogonal_bitmap_intersect_count(bitmap_column, column_to_filter, filter_values)
Parametreler
| Parametre | Açıklama |
|---|---|
bitmap_column |
Toplanacak bitmap sütunu. |
column_to_filter |
Filtreleme için kullanılan boyut sütunu. |
filter_values |
Boyut sütununu filtrelemek için değişken uzunlukta bir değer listesi. |
Örnek
SELECT orthogonal_bitmap_intersect_count(user_id, tag, 1150000, 1150001, 390006)
FROM user_tag_bitmap
WHERE tag IN (1150000, 1150001, 390006);
Çalışma sırasında, 1. Aşama belirtilen etiketlere göre filtreleme yapar, eşleşen tüm etiketler arasında bitmap kesişimini hesaplar ve sonucu paket başına sayar. 2. Aşama, tüm paket bazındaki sayıları toplayarak nihai toplamı oluşturur.
orthogonal_bitmap_union_count
Bitmap değerlerinin birleşimini hesaplar ve sayıyı döndürür. Anlamsal olarak BITMAP_UNION_COUNT ile eşleşir, ancak çalışma paketler arasında dağıtılır.
Sözdizimi
orthogonal_bitmap_union_count(bitmap_column)
Parametreler
| Parametre | Açıklama |
|---|---|
bitmap_column |
Değerleri birleştirilip sayılacak bitmap sütunu. |
Örnek
SELECT orthogonal_bitmap_union_count(user_id)
FROM user_tag_bitmap
WHERE tag IN (1150000, 1150001, 390006);
Şuna eşdeğerdir:
SELECT COUNT(DISTINCT user_id)
FROM user_tag_bitmap
WHERE tag IN (1150000, 1150001, 390006);
Çalışma sırasında, 1. Aşama paket başına bitmap birleşimini hesaplar ve sonucu sayar. 2. Aşama, tüm paket bazındaki sayıları toplayarak nihai toplamı oluşturur.
orthogonal_bitmap_expr_calculate
Bitmap sütunları arasında bir küme ifadesini değerlendirir ve sonucu bitmap olarak döndürür. Yalnızca bir sayı değil, daha fazla işlem için bitmap'in kendisine ihtiyacınız olduğunda bu işlevi kullanın.
Sözdizimi
orthogonal_bitmap_expr_calculate(bitmap_column, filter_column, input_string)
Parametreler
| Parametre | Açıklama |
|---|---|
bitmap_column |
Toplanacak bitmap sütunu. |
filter_column |
Filtreleme için kullanılan boyut sütunu (hesaplama için anahtar sütun). |
input_string |
Anahtar sütun değerleri üzerinde bir küme ifade dizesi. |
input_string aşağıdaki operatörleri destekler:
| Operatör | İşlem |
|---|---|
& |
Kesişim |
| |
Birleşim |
- |
Fark |
^ |
Özel XOR |
\ |
Kaçış karakteri |
Örnek
SELECT orthogonal_bitmap_expr_calculate(
user_id,
tag,
'(833736|999777)&(1308083|231207)&(1000|20000-30000)'
)
FROM user_tag_bitmap
WHERE tag IN (833736, 999777, 130808, 231207, 1000, 20000, 30000);
Çalışma sırasında, 1. Aşama etiket filtresini belirlemek için input_string değerini ayrıştırır, verileri filtreler ve filtrelenen satırlara paket başına bitmap ifadesini uygular. 2. Aşama, tüm paket bazındaki bitmap sonuçlarının birleşimini hesaplar ve nihai bitmap'i döndürür.
orthogonal_bitmap_expr_calculate_count
Bitmap sütunları arasında bir küme ifadesini değerlendirir ve sayıyı döndürür. Sözdizimi ve parametreler orthogonal_bitmap_expr_calculate ile aynıdır.
Sözdizimi
orthogonal_bitmap_expr_calculate_count(bitmap_column, filter_column, input_string)
Parametreler
| Parametre | Açıklama |
|---|---|
bitmap_column |
Toplanacak bitmap sütunu. |
filter_column |
Filtreleme için kullanılan boyut sütunu (hesaplama için anahtar sütun). |
input_string |
Anahtar sütun değerleri üzerinde bir küme ifade dizesi. &, |, -, ^ ve \ operatörlerini destekler. |
Örnek
SELECT orthogonal_bitmap_expr_calculate_count(
user_id,
tag,
'(833736|999777)&(1308083|231207)&(1000|20000-30000)'
)
FROM user_tag_bitmap
WHERE tag IN (833736, 999777, 130808, 231207, 1000, 20000, 30000);
Çalışma sırasında, 1. Aşama input_string değerini ayrıştırır, verileri filtreler, bitmap ifadesini uygular ve sonucu paket başına sayar. 2. Aşama, tüm paket bazındaki bitmap sonuçlarının birleşimini hesaplar ve nihai sayıyı döndürür.
Sonraki Adımlar
SQL referansı — Bitmap işlevleri bölümündeki bitmap işlevlerinin tam listesi