20 Milyon Satır, Üç Motor: Doris, PostgreSQL ve SQL Server’ı Ölçtüm

Çağlar Özenç 12 dk okuma

6 Eylül 2026 düzeltmesi. Ölçümler ve laboratuvar değişmedi; üç çıkarım daraltıldı. 200 milyon satır için verilen doğrusal tahmin kaldırıldı (tek nokta eğri vermez), 1,7 emülasyon katsayısının bölen olarak kullanılmaması gerektiği yazıldı, ve satır sayısı eşitliğinin sonuç eşitliği anlamına gelmediği eklendi.

Birinci parçada Power BI çıkışı için iki açık kaynak katmanı anlattım. Superset raporun yüzü, Doris altındaki motor. Orada verdiğim bütün sayılar dokümantasyondan ve satıcı bloglarından geliyordu.

Bu parçada kendim kurdum. 20 milyon satırlık bir satış tablosu ürettim, aynı CSV’yi Doris’e, PostgreSQL’e ve SQL Server 2025’e yükledim, altı sorguyu üçer kez çalıştırdım ve Superset’i Doris’e bağlayıp dashboard kurdum. Aşağıdaki her sayı bu makinede ölçüldü.

Yarısı da yolunda gitmedi, o kısmı da yazıyorum. Takıldığım yerler genelde bloglarda görünmez ve kurulum süresini asıl onlar ikiye katlar.

Ortam

MacBook, Apple Silicon, 16 GB RAM. Docker Desktop sanal makinesine 12 GB bellek, 8 CPU ve 120 GB disk verdim. Apache Doris 4.0.8 (1 FE + 1 BE), Apache Superset 6.1.0, PostgreSQL 16, SQL Server 2025 CU8 ve Redis 7.

SQL Server’ın bir uyarısı var ve sonuçları okurken şart. Microsoft’un imajı yalnızca amd64 yayınlanıyor, Apple Silicon üzerinde Rosetta emülasyonuyla dönüyor. Doris ve PostgreSQL native arm64 çalışıyor. Emülasyon cezasını aynı makinede ölçtüm: birebir aynı CPU işi amd64 konteynerde 0,29 saniye, arm64’te 0,17 saniye, yani kabaca 1,7 kat. SQL Server sayılarını bu katsayıyı akılda tutarak okuyun. Katsayıyı bölen olarak kullanmayın: 1,7 tek bir CPU işinde ölçüldü, bütün sorguları aynı oranda düzeltmez. Giriş/çıkış, bellek, sorgu planı ve paralellik emülasyondan farklı etkilenir. Bu karşılaştırma bir laboratuvar senaryosunu anlatıyor: tek düğüm, laptop, native arm64 iki motora karşı emülasyondaki bir motor, ve kolon depolamalı bir sistemle B-tree ağırlıklı bir kurulum. Ürünlerin genel sıralaması değil.

İmaj boyutları şaşırtıcı taraftaydı. Doris BE 5,36 GB, FE 2,28 GB. Superset 877 MB, PostgreSQL 474 MB. Doris’in ikilisi tek başına indirilecek 7,6 GB demek ve kısıtlı hattı olan bir ofiste bunu planlamanız gerekiyor.

Veri

Sentetik satış verisi: 20.000.000 satır, 11 kolon, 2023-01-01 ile 2026-08-31 arası. Yanında 5.000 satırlık ürün ve 120 satırlık şube boyut tabloları. Python ile üretimi 95,3 saniye sürdü, dosya 1,4 GB oldu.

Ölçüm bunun üzerine kuruldu. Doris tarafında tablo DUPLICATE KEY(tarih, satis_id), aya göre otomatik aralık bölümleme (44 bölüm oluştu) ve satis_id üzerinde 8 kova. PostgreSQL tarafında aynı tablo, üstüne tarihurun_id ve sube_id için üç B-tree indeks. Yani her iki motora da kendi doğal kurulumunu verdim.

Yükleme

AdımDorisPostgreSQLSQL Server (emüle)
Ham yükleme71,3 sn (280 bin satır/sn)30,8 sn (650 bin satır/sn)112,1 sn (178 bin satır/sn)
İndeks oluşturmayok16,5 sn (3 indeks)119,8 sn (3 indeks)
İstatistikotomatik1,9 sn (VACUUM ANALYZE)47,0 sn (FULLSCAN)
Sorgulanabilir olana kadar71,3 sn49,2 sn278,9 sn

Bu satırı beklemiyordum. Tek bir düz dosyayı içeri almakta PostgreSQL’in COPY komutu Doris’in Stream Load’undan hızlı. Doris o sürede kolon formatına çeviriyor, sıkıştırıyor ve 44 bölüme dağıtıyor, yani karşılaştırma birebir değil. Ama “Doris her şeyde hızlı” cümlesi burada doğru olmuyor.

Depolamada tablo tersine dönüyor:

MotorTabloİndekslerToplam
SQL Server 20251.646 MB1.027 MB2.673 MB
PostgreSQL 161.863 MB399 MB2.263 MB
Apache Doris 4.0.8367 MByok367 MB

Doris ile SQL Server arasında 7,3 kat, PostgreSQL ile arasında 6,2 kat fark var. Kolon bazlı depolama ve sıkıştırmanın somut karşılığı bu. 20 milyon satırda 2 GB’lık fark önemsiz görünebilir, 2 milyar satırda aynı oran 200 GB eder ve yedekleme ile replikasyon maliyetini birlikte büyütür.

Dikkat çeken ayrıntı, SQL Server’ın indekslerinin tablosunun neredeyse üçte ikisi kadar yer kaplaması. Aynı üç indeks PostgreSQL’de 399 MB tutuyor.

Sorgu süreleri

Altı sorgu, her biri üçer kez, Doris’in SQL önbelleği kapalı. İlk koşu soğuk, en iyi koşu ısınmış hali.

SorguDorisPostgreSQLSQL Server (emüle)
Aylık ciro (tam tablo agregasyon)1,40 sn2,79 sn7,95 sn
Kategori x marka (join + group by)1,11 sn2,53 sn6,42 sn
Bölge x kanal (join, son 12 ay)0,45 sn1,02 sn5,39 sn
Aylık tekil müşteri (count distinct)1,72 sn9,08 sn6,28 sn
Filtreli top-100 (sıralama)0,15 sn1,24 sn5,67 sn
Tek gün nokta sorgusu0,02 sn0,03 sn0,12 sn
Toplam4,85 sn16,68 sn31,83 sn

Üç motorun altı sorguda da aynı satır sayısını döndürdüğünü tek tek doğruladım (44, 20, 24, 44, 100 ve 1 satır). Bunun neden önemli olduğu aşağıdaki yedinci maddede yazıyor.

Tek düğüm, laptop, 20 milyon satır. Bu koşullarda Doris PostgreSQL’e göre 3,4 kat hızlı çıktı. Satıcı bloglarının konuştuğu 18 ila 34 kat gibi rakamlar burada yok, çünkü onlar milyar satır ölçeğinde ve çok düğümlü kümelerde ölçülüyor.

SQL Server’ın 31,83 saniyesini olduğu gibi okumayın. O motor emülasyonda çalışıyor ve ölçtüğüm kaba ceza 1,7 kat. Bölünce yaklaşık 19 saniye çıkıyor, yani native çalışsa PostgreSQL ile aynı kulvarda olurdu. Doris’in ikisinden de belirgin hızlı olduğu sonucu bu düzeltmeden sonra da duruyor.

Üç uç nokta ilginç. Tek gün nokta sorgusunda Doris ile PostgreSQL neredeyse eşit (0,02 sn karşı 0,03 sn), çünkü B-tree indeksi tam da bu iş için var. Tekil müşteri sayımında PostgreSQL 9,08 saniyeye çıkıyor ve emülasyondaki SQL Server’ın bile gerisinde kalıyor, count(DISTINCT) PostgreSQL’in zayıf noktası. Filtreli sıralamada ise Doris 0,15 saniyeyle ötekileri açık ara geçiyor.

Yani “Doris alalım” kararını ortalama hız vermiyor. Panonuzda hangi sorgu tipinin ağır bastığı veriyor.

Superset tarafı

Superset’e Doris’i bağlamak sqlalchemy-doris sürücüsü ve şu bağlantı dizesiyle oluyor:

doris://root:@172.28.10.2:9030/dwh

API üzerinden bir veritabanı bağlantısı, bir dataset, dört grafik ve bir dashboard oluşturmak 1,02 saniye sürdü. Superset’in ilk kurulumu (şema göçü, admin kullanıcı, roller) 21 saniye.

Dashboard gerçekten çalıştı ve 20 milyon satırın üzerinden 225 milyarlık ciroyu, 44 aylık trendi ve kanal kırılımını çizdi.

Superset panosu, Apache Doris kaynağı üzerinde dört kart: 20 milyon satırdan hesaplanan toplam ciro, aylık ciro trendi, kanal kırılımı pastası ve şube bazlı ciro sütunları

Apache Superset dashboard’u. Dört grafik de altındaki Apache Doris üzerindeki 20 milyon satırlık satış tablosundan üretildi. Toplam ciro 225 milyar, 44 aylık trend.

SQL Lab da Doris şemalarını listeledi, date_trunc ve count(DISTINCT) içeren sorguyu doğru döndürdü.

Superset SQL Lab ekranında Apache Doris bağlantısıyla çalıştırılan aylık toplama sorgusu ve 12 satırlık sonuç tablosu

Superset SQL Lab, Apache Doris üzerinde aylık ciro ve tekil müşteri sorgusu. Sol tarafta Doris şema ağacı görünüyor.

Grafiklerin veri süreleri şöyle:

Grafik1. istek2. istek3. istek
Toplam ciro4,91 sn0,77 sn0,11 sn
Aylık ciro trendi3,32 sn0,20 sn0,11 sn
Kanal kırılımı2,67 sn0,58 sn0,35 sn
Durum x kanal3,03 sn0,23 sn0,17 sn

İlk istekteki 3 ila 5 saniye Superset’in kendi yükü artı soğuk Doris. Isınınca 0,11 saniyeye iniyor, çünkü Doris’in SQL önbelleği devrede. Gerçek kullanıcı deneyimi bu iki sayının arasında bir yerde.

SQL Server tarafı: bağlanıyor mu?

Buraya kadar Doris’i PostgreSQL ile karşılaştırdım, çünkü birinci parçada önerdiğim göç hedefi PostgreSQL’di. Ama çıkış yapan kurumun kaynak sistemi SQL Server ve doğal soru şu: bu yığın SQL Server ile konuşuyor mu?

Üç yerde de denedim, üçü de çalıştı.

Superset doğrudan SQL Server’a bağlanıyor. İmaja pymssql eklemek yetiyor, bağlantı dizesi mssql+pymssql://sa:parola@host:1433/dwh. Bağlandı ve 20 milyon satırı saydı. Tek pürüz, SQLAlchemy 1.4.54’ün SQL Server 2025’in sürüm numarasını (17.0.4075.5) tanımaması. Uyarı veriyor, çalışmayı engellemiyor.

Doris, SQL Server’ı veri kopyalamadan sorguluyor. JDBC kataloğu kuruluyor:

CREATE CATALOG sqlserver_kaynak PROPERTIES (
  'type'='jdbc',
  'user'='sa',
  'password'='...',
  'jdbc_url'='jdbc:sqlserver://host:1433;DataBaseName=dwh;encrypt=false;trustServerCertificate=true',
  'driver_url'='file:///opt/apache-doris/plugins/jdbc_drivers/mssql-jdbc.jar',
  'driver_class'='com.microsoft.sqlserver.jdbc.SQLServerDriver'
);

Sürücü jar’ını hem FE hem BE konteynerine koymak gerekiyor, tek tarafa koymak yetmiyor. Sonra sqlserver_kaynak.dbo.fact_satis diye sorgulanıyor. Üç aylık kanal kırılımı 7,82 saniyede döndü.

Asıl ilginci çapraz katalog sorgusu. Doris’teki yerel boyut tablosunu SQL Server’daki olgu tablosuyla birleştirdim:

SELECT u.kategori, count(*) AS adet, sum(f.tutar) AS ciro
FROM sqlserver_kaynak.dbo.fact_satis f
JOIN dwh.dim_urun u ON f.urun_id = u.urun_id
WHERE f.tarih >= '2026-07-01'
GROUP BY u.kategori;

8,78 saniyede sonuç verdi. Göç sırasında bunun değeri büyük. Eski ambarı yerinde bırakıp üstünden okuyarak kademeli geçiş yapabiliyorsunuz, önce her şeyi taşıyıp sonra rapor yazmak zorunda değilsiniz.

Ölçüm tarafında SQL Server’ı sonuç tablosuna koydum ama emülasyon uyarısıyla. Yukarıdaki tabloda üçüncü sütun o. Native çalışan bir SQL Server’ın bu sayılardan belirgin daha iyi olacağını varsayın.

Takıldığım yedi nokta

Bu bölüm kurulum süresini ikiye katlayan kısım.

1. Superset’in resmi imajında PostgreSQL sürücüsü yok. Konteyner açılıyor, ModuleNotFoundError: No module named 'psycopg2' deyip ölüyor. Kendi metadata veritabanına bağlanamıyor. psycopg2-binary ve pydoris ekleyen bir türev imaj yazmak zorundasınız. Bende 13 saniye sürdü, ama “resmi imajı çek çalıştır” beklentisi burada bitiyor.

2. Doris Stream Load, konteynerin iç IP’sine yönlendiriyor. FE’nin 8030 portuna yükleme gönderdiğimde HTTP 307 ile BE’nin iç adresine (172.28.10.3:8040) yönlendirdi ve host oraya erişemediği için sessizce boş cevap döndü. 75 saniye boşa gitti. Çözüm, BE’nin yayınlanmış portuna doğrudan göndermek.

3. Docker’ın varsayılan 64 MB’lık /dev/shm boyutu PostgreSQL’i durduruyor. could not resize shared memory segment to 67145376 bytes: No space left on device. Paralel sorgu için gereken dinamik paylaşılan bellek sığmıyor. shm_size: 1gb gerekiyor ve bu compose dosyasında varsayılan gelmiyor.

4. postgres:16-alpine arm64’te büyük tabloda çöküyor. Tam tarama yapan her sorguda server process was terminated by signal 7: Bus error alıp kurtarma moduna giriyor. Aynı veriyle Debian tabanlı postgres:16 imajında tek bir sorun çıkmadı. Apple Silicon üzerinde çalışıyorsanız alpine varyantını veri ambarı testinde kullanmayın.

5. Doris’in SQL önbelleği varsayılan açık ve ölçümü yalan söylüyor. İlk ölçüm turunda ısınmış koşular 0,00 saniye gösterdi. 20 milyon satırlık bir agregasyon 10 milisaniyede bitmiyor. enable_sql_cache varsayılanı true ve kapatmadan yaptığınız her karşılaştırma çöp. Kapatınca aynı sorgu 1,40 saniyeye çıktı.

6. Doris BE, 3 GB bellekle count(DISTINCT) sorgusunu iptal etti. MEM_LIMIT_EXCEEDED, süreç belleği 2,41 GB limitin üstüne çıkmış. 4.0’ın tanıtım metnindeki spill-to-disk özelliğini açmak da kurtarmadı, çünkü süreç zaten limitteydi ve dökecek yer bulamadı. BE’yi yeniden başlatınca aynı sorgu 1,46 saniyede bitti. Doris’in bellek yönetimi PostgreSQL kadar affedici değil, üretimde BE başına önerilen 16 GB’ı ciddiye alın.

7. Ölçümüm sessizce yanlış çıktı ve satır saymasam fark etmeyecektim. Veri üretecim CSV’yi \r\n satır sonuyla yazmış. PostgreSQL’in COPY komutu ve Doris’in Stream Load’u \r karakterini temizledi. SQL Server’ın BULK INSERT komutu, ROWTERMINATOR='0x0a' verdiğim için temizlemedi. SQL Server’da durum alanı 11 karakter oldu, ötekilerde 10. durum='tamamlandi' filtresi kullanan üç sorgu boş küme döndürdü ve hata vermeden ölçüldü, süreler de makul görünüyordu. Yalnızca sonuç satır sayısını kontrol ettiğimde ortaya çıktı. ROWTERMINATOR='0x0d0a' ile yeniden yükledim ve üç motorun da aynı satır sayılarını döndürdüğünü doğruladım. Karşılaştırma yapan herkes süreyle birlikte satır sayısını da yazsın. Bir uyarı da kendime: satır sayısının tutması sonuçların tuttuğunu kanıtlamaz. Bu vakada beni kurtardı çünkü hata boş küme üretiyordu. Ama bir toplama ya da ortalama yanlışsa satır sayısı yine eşit kalır ve hata görünmez. Ölçümü ciddiye alacaksanız değerleri de karşılaştırın; kayan noktada makul bir tolerans kullanın.

Bonus olarak: PostgreSQL veri dizinini macOS bind mount’unda tutunca COPY 53,1 saniye sürdü, Docker named volume’da aynı iş 30,8 saniye. Neredeyse iki kat.

Ne öğrendim

Doris kurulumu beklediğimden temiz. İki süreç, ZooKeeper yok, ayrı koordinatör yok, MySQL istemcisiyle bağlanıp çalışıyorsunuz. Superset ise beklediğimden kirli çıktı, çünkü resmi imaj sürücüsüz geliyor ve üretim için beş parça ayakta tutmanız gerekiyor.

Sorgu tarafında Doris net biçimde hızlı, ama farkın büyüklüğü sorgu tipine bağlı. İndeksli nokta sorgusunda PostgreSQL yakalıyor, ağır agregasyonda arayı açıyor. count(DISTINCT) sorgusunda ise PostgreSQL emülasyondaki SQL Server’ın bile gerisine düşüyor. Depolamada Doris ile SQL Server arasında 7,3 kat fark var ve bu ölçek büyüdükçe donanım faturasına dönüşüyor.

SQL Server tarafında hem Superset hem Doris bağlanıyor ve Doris eski ambarı kopyalamadan sorgulayabiliyor. Göçü tek seferde yapmak zorunda değilsiniz.

20 milyon satırda PostgreSQL hala kullanılabilir durumda, en kötü sorgusu 9 saniye. Ölçtüğüm nokta burası ve tek nokta bir eğri vermez. On kat veriyle sürenin on kat artacağını varsaymak yanlış olur: bellek eşiği aşıldığında, plan değiştiğinde ya da çalışma kümesi diske taştığında eğri kırılır ve genelde daha kötüye kırılır. Söyleyebileceğim şu: bu donanımda 20 milyonda pano hala açılıyor, ve PostgreSQL tarafında en kötü sorgu zaten 9 saniyede. Sizin eşiğinizin nerede olduğunu kendi verinizle ölçmeniz gerekiyor, laboratuvar tam da bunun için açık kaynak.

Laboratuvarı kendi makinenizde kurun

Benim sayılarıma inanmanız gerekmiyor, kendi donanımınızda üretin. Laboratuvarın tamamını açık kaynak olarak yayınladım: compose dosyası, veri üreteci, üç motorun DDL’leri, ölçüm betikleri, Superset kurulumu ve SQL Server federasyonu.

github.com/dmcteknoloji/doris-superset-lab

git clone https://github.com/dmcteknoloji/doris-superset-lab.git
cd doris-superset-lab
bash kur.sh

Sekiz adımda her şeyi kuruyor: kernel ayarı, Superset imajı, konteynerler, şemalar, veri üretimi, üç motora yükleme, indeksler ve istatistikler. Varsayılan 20 milyon satır, bash kur.sh 2000000 diyerek küçültebilirsiniz. Docker sanal makinesine 10 GB bellek ve 60 GB boş disk gerekiyor, ilk çalıştırmada yaklaşık 9 GB imaj iniyor.

Sonra bash olc.sh ve bash olc-mssql.sh ölçümü çalıştırıyor, python3 superset-kur.py dashboard’u kuruyor. Depodaki README yukarıdaki yedi maddenin hepsini ve çözümlerini de anlatıyor.

x86 bir sunucuda çalıştıran olursa sayıları merak ediyorum, çünkü orada üç motor da native olur ve SQL Server sütunu emülasyon cezasından kurtulur.

Sık sorulanlar

Apache Doris PostgreSQL ve SQL Server’dan ne kadar hızlı?

20 milyon satırda, tek düğümde ve laptop ölçeğinde altı sorgunun toplamında PostgreSQL’e göre 3,4 kat hızlı çıktı. SQL Server emülasyonda çalıştığı için doğrudan kıyaslanmıyor, emülasyon cezası düzeltildiğinde PostgreSQL ile aynı kulvara geliyor. Fark sorgu tipine göre değişiyor.

Hangi sorguda hangi motor öne çıkıyor?

İndeksli tek gün sorgusunda Doris ile PostgreSQL neredeyse eşit. Tekil müşteri sayımında PostgreSQL 9,08 saniyeye çıkıp emülasyondaki SQL Server’ın bile gerisinde kalıyor. Filtreli sıralamada Doris 0,15 saniyeyle açık ara önde.

Apache Doris ne kadar disk kullanıyor?

Aynı 20 milyon satır Doris’te 367 MB, PostgreSQL’de tablo ve indeksler dahil 2.263 MB, SQL Server’da 2.673 MB yer kapladı. Doris ile SQL Server arasında 7,3 kat fark var.

Apache Doris SQL Server’ı sorgulayabilir mi?

Evet. JDBC kataloğu kurulunca SQL Server’daki tabloları veri kopyalamadan sorgulayabiliyor. Doris’teki yerel bir boyut tablosuyla SQL Server’daki olgu tablosunu tek sorguda birleştirmek de çalışıyor. Sürücü jar’ı hem FE hem BE konteynerine konulmalı.

Superset’in resmi Docker imajı neden hemen kapanıyor?

Resmi imaj PostgreSQL sürücüsünü içermiyor ve kendi metadata veritabanına bağlanamadan ModuleNotFoundError vererek ölüyor. psycopg2-binary ekleyen bir türev imaj üretmek gerekiyor.

Bu laboratuvarı kendim kurabilir miyim?

Evet, tamamı açık kaynak. github.com/dmcteknoloji/doris-superset-lab deposunu klonlayıp bash kur.sh demek yeterli. Docker sanal makinesine 10 GB bellek ve 60 GB boş disk gerekiyor.

Bu işi birlikte yapmak isterseniz

DMC Bilgi Teknolojileri olarak on beş yılı aşkın süredir SQL Server ve veritabanı tarafında çalışıyoruz. Power BI çıkışı sorulduğunda işe kapsamı sayıya dökerek başlıyoruz, ürün önererek değil. Kaç Power BI raporu, kaç SSRS raporu, kaç SSIS paketi, kaç DAX ölçüsü, kaç aktif kullanıcı, hangi veri kaynakları.

Altındaki katman görünmeden verilen takvim tahmin oluyor ve göç projeleri genelde tam buradan yarıda kalıyor.

Yaptığımız işler: SQL Server sağlık ve güvenlik değerlendirmesi, SQL Server’dan PostgreSQL’e geçiş, veri ambarının yeniden kurgulanması, raporlama katmanının taşınması ve devamında yönetilen DBA hizmeti. Değerlendirme aşaması kısa ve somut, çıktısı bulgu listesi ile takvim.

iletisim@dmcteknoloji.com · dmcteknoloji.com · 0212 945 61 66

Yorum yaz

Yorumlar onaydan sonra yayınlanır. E-posta adresiniz yayınlanmaz ve üçüncü tarafla paylaşılmaz.