Bilgi Bankası
ClickHousePerformans ve kapasite 15 dk 14.06.2026

ClickHouse SELECT sorguları neden yavaşlar ve nasıl hızlandırılır?

ClickHouse yavaşladığında ilk tepki genellikle “bu motor hızlı değil miydi?” olur. Aslında ClickHouse hâlâ hızlıdır; ama yanlış sorgu, yanlış ORDER BY veya fazla veri okuma onu gereksiz yere koşturur. Bu yazı SELECT tarafında önce ne kadar veri okuduğunuzu buldurur, sonra okunan veriyi azaltmanın yollarını anlatır.

Bu yazı sana şu durumda yardımcı olur
  • Pano sorguları saniyeler yerine onlarca saniye sürüyor
  • CPU yükseliyor ama sonuç seti küçük dönüyor
  • Aynı tablo bazı filtrelerle hızlı, bazı filtrelerle yavaş çalışıyor
  • SELECT * kullanılan raporlar zamanla ağırlaşıyor
  • FINAL, geniş JOIN veya fonksiyonlu WHERE koşulları sorguyu uzatıyor
Yazıyı bitirince

Yavaş SELECT için query_log okur, EXPLAIN indexes çıktısıyla pruning olup olmadığını anlarsınız. “Daha büyük makine mi, daha iyi sorgu mu, özet tablo mu?” kararını daha sağlam verebilirsiniz.

TürkDB açısından ürünleşme notu

Bu bölüm, TürkDB’nin ilgili problemi hangi ürün ilkeleri ve kontrol noktalarıyla ele alacağını anlatır. Kapsam, gerçek iş yükü ve ihtiyaçla birlikte netleşir.

TürkDB burada sorguyu sihirli biçimde düzeltmez; bu iyi bir şeydir, çünkü sorun çoğu zaman modelleme tarafındadır. TürkDB güvenli bağlantı, olay görünürlüğü ve kapasite sinyallerini verir; siz de ölçek kararını optimizasyonu gördükten sonra verirsiniz.

1. İlk soru: Bu sorgu ne kadar veri okuyor?

ClickHouse yavaşlığında sonuç setinin küçük olması çok yanıltıcıdır. Sorgu ekrana 50 satır döndürebilir ama arka planda milyarlarca satır tarıyor olabilir. Bu yüzden ilk bakılacak metrik sadece duration değil; read_rows ve read_bytes değeridir.

Kullanıcının gerçek sorusu genellikle “Bu sorgu neden yavaş?”tır. Cevap çoğu zaman şudur: ClickHouse gereğinden fazla parça, satır veya kolon okuyor. Aşağıdaki sorgu son yavaş SELECT işlemlerini hangi tabloya, kaç satıra ve kaç byte okumaya mal olduğunu gösterir.

Son yavaş SELECT sorgularını ölçme

clickhouse-query-log.sql
SELECT
  event_time,
  query_duration_ms,
  read_rows,
  formatReadableSize(read_bytes) AS read_size,
  result_rows,
  memory_usage,
  left(query, 220) AS query
FROM system.query_log
WHERE type = 'QueryFinish'
  AND event_time > now() - INTERVAL 1 HOUR
  AND query_kind = 'Select'
ORDER BY query_duration_ms DESC
LIMIT 20;

read_rows yüksek, result_rows düşükse problem çoğunlukla veri eleme tarafındadır; daha fazla CPU eklemekten önce sorgunun okuduğu veri azaltılmalıdır.

2. EXPLAIN ile primary key ve partition pruning kontrolü

ClickHouse klasik B-tree indeks mantığıyla çalışmaz. MergeTree tabloda ORDER BY ifadesi primary key yapısını belirler; ClickHouse bu sıralama sayesinde granule atlar. WHERE koşulunuz ORDER BY sırasının sol tarafını kullanmıyorsa veri atlama zayıflar.

Örneğin tablo ORDER BY (tenant_id, event_name, created_at) ile kurulmuşsa tenant_id ve event_name filtreleri çok değerlidir. Sadece created_at filtresi kullanırsanız ClickHouse tarih aralığını görse bile tenant boyutunda daha geniş okuma yapabilir.

  • WHERE koşulu ORDER BY ifadesinin ilk kolonlarını kullanıyor mu?
  • Tarih filtresi partition anahtarıyla uyumlu mu?
  • WHERE içinde kolona fonksiyon uygulanıp pruning bozuluyor mu?
  • Sorgu ihtiyacı olmayan kolonları SELECT * ile okuyor mu?
  • FINAL kullanımı gerçekten gerekli mi, yoksa tablo modeli değişmeli mi?

Pruning kontrolü için EXPLAIN

clickhouse-explain.sql
EXPLAIN indexes = 1
SELECT event_name, count()
FROM events
WHERE tenant_id = 'acme'
  AND event_name = 'ödeme akışı_completed'
  AND created_at >= now() - INTERVAL 7 DAY
GROUP BY event_name;

Fonksiyonlu WHERE yerine aralık kullanma

clickhouse-where.sql
-- Kötü: created_at üzerinde fonksiyon pruning'i zayıflatabilir
WHERE toDate(created_at) = today()

-- İyi: ham kolon üzerinde aralık koşulu
WHERE created_at >= today()
  AND created_at < today() + INTERVAL 1 DAY

3. Tablo tasarımı sorgu niyetine uymuyorsa düzeltme nerede yapılır?

Sorgu her zaman tenant_id, event_name ve zaman aralığıyla çalışıyorsa tablo ORDER BY ifadesi bunu yansıtmalıdır. Buna karşılık kullanıcı_id üzerinden nokta arama yapıyorsanız başka bir projection, materialized view veya ayrı tablo gerekebilir. Tek tabloyla her sorguyu mükemmel yapmak çoğu zaman mümkün değildir.

Partition anahtarı performans indeksinden çok veri yönetimi sınırıdır. Çok ince partition, parça sayısını artırır; çok kaba partition ise silme ve yaşam döngüsü işlerini zorlaştırır. Zaman serisi event verisinde aylık veya günlük partition kararı veri hacmine göre verilmelidir.

Pano sorgusu için temel tablo

events-table.sql
CREATE TABLE events
(
  tenant_id String,
  event_name LowCardinality(String),
  user_id String,
  created_at DateTime,
  properties String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (tenant_id, event_name, created_at);

Sık kullanılan metrik için özet tablo

events-rollup.sql
CREATE MATERIALIZED VIEW events_daily_mv
ENGINE = SummingMergeTree
PARTITION BY toYYYYMM(day)
ORDER BY (tenant_id, event_name, day)
AS
SELECT
  tenant_id,
  event_name,
  toDate(created_at) AS day,
  count() AS events
FROM events
GROUP BY tenant_id, event_name, day;

Pano aynı agregasyonu sürekli çalıştırıyorsa, ham tabloyu her seferinde taramak yerine özet tablo kullanmak daha doğru çözümdür.

4. Hızlandı mı, yoksa sadece şanslı bir koşu mu?

Değişiklikten sonra yalnızca “süre düştü mü?” diye bakmayın. Aynı sorgunun read_rows, read_bytes, memory_usage ve query_duration_ms değerlerini önce/sonra karşılaştırın. Okunan veri azalmadıysa hızlanma geçici önbellek etkisi, daha sakin bir an veya tesadüf olabilir.

TürkDB tarafındaki ilişki burada operasyonel karardır: önce sorgu ve tablo tasarımını ölçümle düzeltirsiniz; hâlâ kapasite sınırına geliyorsanız cluster tier veya kaynak artışı anlamlı hale gelir.

TürkDB ve ClickHouse çalışma akışı

turkdb-clickhouse-diagnose.sh
turkdb cluster get product-analytics
turkdb cluster events product-analytics --limit 20
turkdb connect product-analytics --no-tunnel
Bu TürkDB bloğu kavramsal ürün akışını anlatır; mevcut çalışan komut, garanti edilen özellik veya teslim tarihi vaadi olarak okunmamalıdır.

Bu komutlar sorgu optimizasyonunun yerine geçmez; doğru cluster, bağlantı ve olay durumunu doğrulayıp ClickHouse içindeki query_log/EXPLAIN incelemesine güvenli zemin hazırlar.

Devam etmek istersen

Sorunu motor bazında derinleştirin

Benzer belirtiler farklı motorlarda farklı nedenlere dayanır; yayınlanan tüm rehberleri ana sayfadan takip edebilirsiniz.

Tüm makaleler