DuckDB'de Parquet Sayfalama: file_row_number mi, OFFSET mi?
DuckDB'de Parquet sayfalamada file_row_number ile OFFSET karşılaştırması: performans farkı ve gizli veri bütünlüğü riski.
Yirmi milyon satırlık bir Parquet dosyasını sayfa sayfa döndüren stateless bir servis için DuckDB'de iki yaklaşım karşılaştırıldı: klasik LIMIT/OFFSET ve read_parquet'in file_row_number seçeneğiyle satır aralığı filtreleme. 163 row group içeren dosyada satır aralığı yaklaşımı OFFSET'e göre 2.53 kat daha hızlı çıktı ve bu sonuç 37 denemenin tamamında tekrarlandı; ancak kazanç tamamen dosyanın kaç row group'a bölündüğüne bağlı, tek row group'luk dosyalarda neredeyse kayboluyor.
Beklenmedik bulgu ise DuckDB'nin OFFSET sorgularını arka planda file_row_number tabanlı bir hash join'e dönüştürüp benzer row group atlamasını zaten yaptığı; bu yüzden OFFSET kuadratik değil. Ancak bu rewrite yalnızca LIMIT değeri 1.000.000 satırın altındayken (LIMIT_MAX_VAL ve late_materialization_max_rows ayarlarına bağlı bir eşik) tetikleniyor; eşik aşılınca veya WHERE eklenince fark 5-6 kata çıkıyor.
Asıl kritik nokta performans değil doğruluk: LIMIT/OFFSET'in ORDER BY olmadan hiçbir sıralama garantisi yok. preserve_insertion_order kapatılıp çoklu thread ile sayfalama yapıldığında toplam satır sayısı tam 20 milyon çıkmasına rağmen verinin yaklaşık %30'u ya kayboluyor ya da tekrar ediyor ve hata fırlamıyor. Bu da satır sayısı doğrulamasının export bütünlüğü için yetersiz olduğunu, hash tabanlı doğrulamanın gerekli olduğunu gösteriyor.
Bu sentez, kaynağından yapay zeka tarafından üretildi; insan editör ya da elle onay adımı yoktur. Nasıl çalışıyoruz