Oracle performans kitaplarının çoğu, kariyerleri OLTP'de — sipariş girişi, bankacılık işlemleri, perakende — şekillenmiş DBA'ler tarafından yazılmıştır. Tavsiyeleri bu iş yükleri için sağlamdır. Aynı tavsiyeler, bir emeklilik aktüerya koşumuna, bir Solvency II mutabakatına veya her gece yıllarca bitemporal geçmişi öğütmek zorunda olan bir sigorta rezerv hesaplama hattına uygulandığında ise yanlıştır — çoğu zaman tehlikeli biçimde yanlış.
Türk emeklilik ve sigorta şirketlerinde bu sistemleri iyileştirmek için yeterince zaman harcadım; kitap ile veri merkezi zemini arasındaki uçurumu biliyorum. İşte kitapların atladıkları.
İş Yükü Sandığınız Şey Değil
Bir emeklilik değerleme koşumu bir sorgu değildir. Şu işleri yapan bir toplu iş hattıdır:
- Birden fazla tarihsel anlık görüntüde on milyonlarca poliçe satırını okur
- Katkı geçmişleri, fon birim fiyat tabloları ve ölüm varsayımları ile birleştirme yapar
- Bir sonraki aşamanın okuyacağı ara sonuçları yazar
- Aktüerya ekibi sabah 7'de gelmeden bitmek zorundadır
Saniyenin altında yanıt bekleyen bir kullanıcı yok. Tek bir sorgunun 40 dakika sürmesi kimsenin umurunda değil. Önemli olan, iş hattının penceresini kaçırıp kaçırmadığı. Bu tek gözlem, geleneksel ayar tavsiyelerinin kabaca yarısını geçersiz kılar.
Index'ler: Finansal İş Yüklerinde En Çok Aşırı Kullanılan Araç
Sorgu yavaşladığında kitabın refleksi: index ekle. Emeklilik toplu iş bağlamında bu çoğu zaman yanlış hamledir.
POLICY_VALUATION tablosunun %80'ine dokunan tipik bir rezerv hesaplamasını düşünün. Optimizer'ın paralel sorgu ile full table scan seçmesi gerekir. Ama iyi niyetli bir geliştirici ad-hoc raporlamayı desteklemek için altı index eklediği için, CBO arada bir index range scan seçer ve iş 25 dakikadan 4 saate fırlar.
Gerçekten işe yarayanlar:
- Yalnızca raporlama için var olan index'leri, esas olarak toplu yüklenen tablolardan kaldırın. Raporlamayı bir replikaya veya materialized view katmanına taşıyın.
- Toplu iş SQL'inde
FULLvePARALLELhint'lerini agresif şekilde kullanın. Hint'lerin code smell olmadığı az sayıdaki yerden biri burası — erişim desenini optimizer'dan daha iyi biliyorsunuz ve değişmeyeceğini de biliyorsunuz. PRODUCT_CODE,STATUS,FUND_TYPEgibi düşük kardinaliteli sütunlarda bitmap index'leri tercih edin — tablo eşzamanlı DML'e maruz kalmıyorsa. OLTP trafiği olmayan gecelik bir toplu iş penceresinde, kılavuzlardaki kilitleme itirazları geçerli değildir.
Bitemporal Sorgular Optimizer'ın Varsayımlarını Kırar
Sigorta ve emeklilik verileri neredeyse her zaman bitemporal'dır: her satırın bir iş etki tarihi aralığı (VALID_FROM, VALID_TO) ve bir sistem işlem tarihi aralığı (KNOWN_FROM, KNOWN_TO) vardır. Düzenleyici sorgular rutin olarak şunu sorar: 15 Mart 2023 itibarıyla bilindiği şekliyle, 31 Aralık 2022'de rezervin ne olduğuna inanıyorduk?
CBO'nun dört sütunlu aralık koşulları üzerinde seçiciliği tahmin etmek için iyi bir yolu yok. Size iki kat büyüklük mertebesinde hatalı cardinality tahminleri verir ve plan da çöp olur.
Gerçekten yardımcı olanlar:
- Bitemporal sütun grupları üzerinde extended statistics.
(VALID_FROM, VALID_TO, KNOWN_FROM, KNOWN_TO)üzerindeDBMS_STATS.CREATE_EXTENDED_STATSopsiyonel değildir. KNOWN_FROMaralığına göre partition'layın,VALID_FROMaralığına göre subpartition yapın. Çoğu düzenleyici sorgu, belirli bir tarihte bilinen duruma sabitlendiği için partition pruning anlamlı hale gelir.- "Güncel görünümü" (
KNOWN_TO = DATE '9999-12-31' AND VALID_TO = DATE '9999-12-31') ayrı bir fiziksel tablo veya partition olarak materialize edin. Operasyonel sorguların %90'ı yalnızca bu dilime vurur. Bunu küçük ve sıkı index'li tutun; tarihsel partition'lar geniş kalsın ve taransın.
Mutabakat Yükleri Farklı Bir Hayvandır
Düzenleyici mutabakat — defter bakiyelerini poliçe düzeyindeki detayla eşleştirme, fon muhasebesini saklayıcı beslemeleriyle mutabık kılma — kendine özgü bir patolojiye sahiptir. Hiçbir zaman temiz birleştirilmek üzere tasarlanmamış doğal anahtarlar üzerinde, yuvarlama toleransları ve tarih hizalama kuralları birleştirme koşuluna gömülmüş halde, iki büyük veri setini birleştiriyorsunuz.
Kitap der ki: hash join, küçük tarafın PGA'ya sığdığından emin ol. Güzel. Ama küçük taraf 18 milyon satır, PGA_AGGREGATE_TARGET'ınız 40 eşzamanlı oturumda 8 GB ve temp'e spill edeceksiniz.
Pratik hamleler:
- Mutabakat girdilerini, birleştirme anahtarları zaten normalize edilmiş (yuvarlanmış tutarlar, kanonik tarih formatı, kırpılmış tanımlayıcılar) amaca özel tablolara stage edin. Bunu her mutabakat sorgusunun içinde değil, bir kez yapın.
PARALLEL'i mantıklı bir DOP ile kullanın —DEFAULTayarıyla değil. 32 çekirdekli bir kutuda dört mutabakat işi eşzamanlı çalışırken, iş başınaPARALLEL 4, her seferindePARALLEL 16'yı geçer. Varsayılan ayarlar tek iş yükünün siz olduğunuzu varsayar.- Tarihsel mutabakat sonuçlarını HCC ile sıkıştırın (
COLUMN STORE COMPRESS FOR QUERY HIGH). Denetçiler bu verilere geri döner; mutabakatı yeniden çalıştırmak istemezsiniz. Tablo şeklindeki finansal veriler için 8-12 kat depolama tasarrufu tipiktir.
İstatistikler, Üretimdeki Felaketlerin Çoğunun Başladığı Yerdir
Varsayılan GATHER_STATS_JOB her gece AUTO_SAMPLE_SIZE ile çalışır. OLTP için iyi. Ama gece 2'de toplu bir yükleme 40 milyon satır eklediği ve gece 3'te bir değerleme işinin bunları okuduğu bir sistemde, stats işi henüz çalışmamıştır. Optimizer yeni partition'ın sıfır satıra sahip olduğunu düşünür ve nested loop join seçer. 20 dakika sürmesi gereken iş altı saat çalışır.
Ne yapmalı:
- Her önemli yükleme adımının sonunda istatistikleri açıkça toplayın. Scheduler'a güvenmeyin.
- Değişken staging tabloları üzerinde istatistikleri kilitleyin ve
DBMS_STATS.SET_TABLE_STATSile manuel olarak temsili istatistikler sağlayın. Optimizer'ın doğru sayılardan çok makul sayılara ihtiyacı vardır. - Partition'lı tablolarda incremental statistics kullanın. Bu olmadan her gecelik istatistik toplama, global istatistikleri güncellemek için tüm tabloyu yeniden tarar. Bununla yalnızca yeni partition taranır.
Asıl Önemli Olan Şeyler
Bu sistemleri yıllarca ayarladıktan sonra, iğneyi oynatan kollar, kitapların vurguladıkları değil:
- Erişim desenine hizalanmış partition'lama stratejisi — genel bir en iyi uygulamaya değil.
- Açık istatistik yönetimi — veritabanı düzeyinde değil, iş hattı düzeyinde.
- Kontrollü DOP ile paralel sorgunun agresif kullanımı, eşzamanlı iş yüküne göre boyutlandırılmış.
- Soğuk ve ılık veriler için HCC sıkıştırması, yer tasarrufu kadar tarama performansını da iyileştirir.
- Toplu iş tablolarındaki raporlama index'lerini öldürmek ve raporlamayı ayrı bir katmana itmek.
Bunların hiçbiri egzotik değil. Hepsi belgelerin bir yerinde mevcut. Ama kitaplar bunları kenar durum tavsiyesi olarak çerçeveler ve varsayılan örnekler sizi finansal bir toplu iş yükünü sessizce yok edecek OLTP desenlerine doğru iter.
Ayar içgüdüleriniz işlemsel sistemlerde şekillendiyse, bir emeklilik veya sigorta şirketinde unutmanız gereken ilk şey, tek bir sorgu için optimize etme refleksidir. İş hattı, pencere ve düzenleyici için optimize edin. Sorgu planı, bu kararların aşağı akışıdır.