* split up select.md * array-join.md basic refactoring * distinct.md basic refactoring * format.md basic refactoring * from.md basic refactoring * group-by.md basic refactoring * having.md basic refactoring * additional index.md refactoring * into-outfile.md basic refactoring * join.md basic refactoring * limit.md basic refactoring * limit-by.md basic refactoring * order-by.md basic refactoring * prewhere.md basic refactoring * adjust operators/index.md links * adjust sample.md links * adjust more links * adjust operatots links * fix some links * adjust aggregate function article titles * basic refactor of remaining select clauses * absolute paths in make_links.sh * run make_links.sh * remove old select.md locations * translate docs/es * translate docs/fr * translate docs/fa * remove old operators.md location * change operators.md links * adjust links in docs/es * adjust links in docs/es * minor texts adjustments * wip * update machine translations to use new links * fix changelog * es build fixes * get rid of some select.md links * temporary adjust ru links * temporary adjust more ru links * improve curly brace handling * adjust ru as well * fa build fix * ru link fixes * zh link fixes * temporary disable part of anchor checks
15 KiB
machine_translated | machine_translated_rev | toc_priority | toc_title |
---|---|---|---|
true | 72537a2d52 |
36 | CollapsingMergeTree |
CollapsingMergeTree
Motor devralır MergeTree ve veri parçaları birleştirme algoritmasına çöken satırların mantığını ekler.
CollapsingMergeTree
sıralama anahtarındaki tüm alanlar zaman uyumsuz olarak siler (daraltır) satır çiftleri (ORDER BY
) belirli alan hariç eşdeğerdir Sign
hangi olabilir 1
ve -1
değerler. Çift olmayan satırlar tutulur. Daha fazla bilgi için bkz: Çökme belgenin bölümü.
Motor depolama hacmini önemli ölçüde azaltabilir ve SELECT
sonuç olarak sorgu.
Tablo oluşturma
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = CollapsingMergeTree(sign)
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
Sorgu parametrelerinin açıklaması için bkz. sorgu açıklaması.
CollapsingMergeTree Parametreleri
-
sign
— Name of the column with the type of row:1
is a “state” satır,-1
is a “cancel” satır.Column data type —
Int8
.
Sorgu yan tümceleri
Oluştururken bir CollapsingMergeTree
tablo, aynı sorgu yan tümceleri oluşturul ,urken olduğu gibi gerekli MergeTree
Tablo.
Bir tablo oluşturmak için kullanımdan kaldırılan yöntem
!!! attention "Dikkat" Bu yöntemi yeni projelerde kullanmayın ve mümkünse eski projeleri yukarıda açıklanan yönteme geçin.
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE [=] CollapsingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, sign)
Hariç tüm parametreler sign
içinde olduğu gibi aynı anlama sahip MergeTree
.
-
sign
— Name of the column with the type of row:1
— “state” satır,-1
— “cancel” satır.Column Data Type —
Int8
.
Çökme
Veriler
Bazı nesneler için sürekli değişen verileri kaydetmeniz gereken durumu düşünün. Bir nesne için bir satıra sahip olmak ve herhangi bir değişiklikte güncellemek mantıklı geliyor, ancak güncelleme işlemi dbms için pahalı ve yavaş çünkü depolama alanındaki verilerin yeniden yazılmasını gerektiriyor. Verileri hızlı bir şekilde yazmanız gerekiyorsa, güncelleme kabul edilemez, ancak bir nesnenin değişikliklerini sırayla aşağıdaki gibi yazabilirsiniz.
Belirli sütunu kullanın Sign
. Eğer Sign = 1
bu, satırın bir nesnenin durumu olduğu anlamına gelir, diyelim ki “state” satır. Eğer Sign = -1
aynı özelliklere sahip bir nesnenin durumunun iptali anlamına gelir, diyelim ki “cancel” satır.
Örneğin, kullanıcıların bazı sitelerde ne kadar sayfa kontrol ettiğini ve ne kadar süre orada olduklarını hesaplamak istiyoruz. Bir anda kullanıcı etkinliği durumu ile aşağıdaki satırı yazıyoruz:
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
Bir an sonra kullanıcı aktivitesinin değişikliğini kaydedip aşağıdaki iki satırla yazıyoruz.
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
İlk satır, nesnenin (kullanıcı) önceki durumunu iptal eder. İptal edilen durumun sıralama anahtar alanlarını kopyalamalıdır Sign
.
İkinci satır geçerli durumu içerir.
Sadece kullanıcı etkinliğinin son durumuna ihtiyacımız olduğu için, satırlar
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
│ 4324182021466249494 │ 5 │ 146 │ -1 │
└─────────────────────┴───────────┴──────────┴──────┘
bir nesnenin geçersiz (eski) durumunu daraltarak silinebilir. CollapsingMergeTree
veri parçalarının birleştirilmesi sırasında bunu yapar.
Neden her değişiklik için 2 satıra ihtiyacımız var Algoritma paragraf.
Bu yaklaşımın kendine özgü özellikleri
- Verileri yazan program, iptal edebilmek için bir nesnenin durumunu hatırlamalıdır. “Cancel” dize, sıralama anahtar alanlarının kopyalarını içermelidir. “state” dize ve tersi
Sign
. Bu depolama başlangıç boyutunu artırır ama hızlı bir şekilde veri yazmak için izin verir. - Sütunlardaki uzun büyüyen diziler, yazma yükü nedeniyle motorun verimliliğini azaltır. Daha basit veriler, verimlilik o kadar yüksek olur.
- Bu
SELECT
sonuçlara itiraz değişiklikler tarihin tutarlılık bağlıdır. Ekleme için veri hazırlarken doğru olun. Tutarsız verilerde öngörülemeyen sonuçlar elde edebilirsiniz, örneğin, oturum derinliği gibi negatif olmayan metrikler için negatif değerler.
Algoritma
ClickHouse veri parçalarını birleştirdiğinde, her ardışık satır grubu aynı sıralama anahtarıyla (ORDER BY
) en fazla iki satır reduceda indir isgen ,ir, biri Sign = 1
(“state” satır) ve başka bir Sign = -1
(“cancel” satır). Başka bir deyişle, girişler çöker.
Elde edilen her veri parçası için ClickHouse kaydeder:
- Birincilik “cancel” ve son “state” satır sayısı ise “state” ve “cancel” satırlar eşleşir ve son satır bir “state” satır.
- Son “state” satır, daha varsa “state” satırlar daha “cancel” satırlar.
- Birincilik “cancel” satır, daha varsa “cancel” satırlar daha “state” satırlar.
- Diğer tüm durumlarda satırların hiçbiri.
Ayrıca en az 2 tane daha olduğunda “state” satırlar daha “cancel” satırlar veya en az 2 tane daha “cancel” r rowsows th thenen “state” satırlar, birleştirme devam eder, ancak ClickHouse bu durumu mantıksal bir hata olarak değerlendirir ve sunucu günlüğüne kaydeder. Aynı veriler birden çok kez eklendiğinde, bu hata oluşabilir.
Bu nedenle, çöken istatistik hesaplama sonuçlarını değiştirmemelidir. Değişiklikler yavaş yavaş çöktü, böylece sonunda hemen hemen her nesnenin sadece son durumu kaldı.
Bu Sign
birleştirme algoritması, aynı sıralama anahtarına sahip tüm satırların aynı sonuçtaki veri bölümünde ve hatta aynı fiziksel sunucuda olacağını garanti etmediğinden gereklidir. ClickHouse süreci SELECT
birden çok iş parçacığına sahip sorgular ve sonuçtaki satırların sırasını tahmin edemez. Tamamen almak için bir ihtiyaç varsa toplama gereklidir “collapsed” veri CollapsingMergeTree
Tablo.
Daraltmayı sonuçlandırmak için bir sorgu yazın GROUP BY
yan tümce ve işareti için hesap toplama işlevleri. Örneğin, miktarı hesaplamak için kullanın sum(Sign)
yerine count()
. Bir şeyin toplamını hesaplamak için şunları kullanın sum(Sign * x)
yerine sum(x)
, ve böylece, ve ayrıca ekleyin HAVING sum(Sign) > 0
.
Toplanan count
, sum
ve avg
bu şekilde hesaplanmış olabilir. Toplanan uniq
bir nesnenin en az bir durumu çökmüş değilse hesaplanabilir. Toplanan min
ve max
hesaplan becauseamadı çünkü CollapsingMergeTree
daraltılmış durumların değerleri geçmişini kaydetmez.
Toplama olmadan veri ayıklamanız gerekiyorsa (örneğin, en yeni değerleri belirli koşullarla eşleşen satırların mevcut olup olmadığını kontrol etmek için) FINAL
değiştirici için FROM
yan. Bu yaklaşım önemli ölçüde daha az etkilidir.
Kullanım örneği
Örnek veriler:
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
│ 4324182021466249494 │ 5 │ 146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
Tablonun oluşturulması:
CREATE TABLE UAct
(
UserID UInt64,
PageViews UInt8,
Duration UInt8,
Sign Int8
)
ENGINE = CollapsingMergeTree(Sign)
ORDER BY UserID
Veri ekleme:
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, 1)
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, -1),(4324182021466249494, 6, 185, 1)
Biz iki kullanın INSERT
iki farklı veri parçası oluşturmak için sorgular. Verileri bir sorgu ile eklersek ClickHouse bir veri parçası oluşturur ve hiç bir birleştirme gerçekleştirmez.
Veri alma:
SELECT * FROM UAct
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
Ne görüyoruz ve nerede çöküyor?
İki ile INSERT
sorgular, 2 Veri parçası oluşturduk. Bu SELECT
sorgu 2 iş parçacığında yapıldı ve rastgele bir satır sırası aldık. Veri parçalarının henüz birleştirilmediği için çökme gerçekleşmedi. ClickHouse biz tahmin edemez bilinmeyen bir anda veri kısmını birleştirir.
Böylece toplama ihtiyacımız var:
SELECT
UserID,
sum(PageViews * Sign) AS PageViews,
sum(Duration * Sign) AS Duration
FROM UAct
GROUP BY UserID
HAVING sum(Sign) > 0
┌──────────────UserID─┬─PageViews─┬─Duration─┐
│ 4324182021466249494 │ 6 │ 185 │
└─────────────────────┴───────────┴──────────┘
Toplamaya ihtiyacımız yoksa ve çökmeyi zorlamak istiyorsak, şunları kullanabiliriz FINAL
değiştirici için FROM
yan.
SELECT * FROM UAct FINAL
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
Verileri seçmenin bu yolu çok verimsizdir. Büyük masalar için kullanmayın.
Başka bir yaklaşım örneği
Örnek veriler:
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
│ 4324182021466249494 │ -5 │ -146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
Fikir, birleştirmelerin yalnızca anahtar alanları hesaba katmasıdır. Ve içinde “Cancel” satır işareti sütununu kullanmadan toplanırken satırın önceki sürümünü eşitleyen negatif değerleri belirtebiliriz. Bu yaklaşım için veri türünü değiştirmek gerekir PageViews
,Duration
uint8 -> Int16 negatif değerlerini saklamak için.
CREATE TABLE UAct
(
UserID UInt64,
PageViews Int16,
Duration Int16,
Sign Int8
)
ENGINE = CollapsingMergeTree(Sign)
ORDER BY UserID
Yaklaşımı test edelim:
insert into UAct values(4324182021466249494, 5, 146, 1);
insert into UAct values(4324182021466249494, -5, -146, -1);
insert into UAct values(4324182021466249494, 6, 185, 1);
select * from UAct final; // avoid using final in production (just for a test or small tables)
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
SELECT
UserID,
sum(PageViews) AS PageViews,
sum(Duration) AS Duration
FROM UAct
GROUP BY UserID
```text
┌──────────────UserID─┬─PageViews─┬─Duration─┐
│ 4324182021466249494 │ 6 │ 185 │
└─────────────────────┴───────────┴──────────┘
select count() FROM UAct
┌─count()─┐
│ 3 │
└─────────┘
optimize table UAct final;
select * FROM UAct
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘