Sorunun geçmişi: Zamansal aralık analizi, 1970'lerden beri ilişkisel veritabanlarını zorlamıştır çünkü SQL, başlangıçta doğal aralık türleri olmadan tasarlanmıştır. Erken çözümler, aralıklar arasında imleç tabanlı yinelemelere veya Kartezyen çarpanlara dayanmaktaydı ve bu da kare karmaşıklığa neden olmaktaydı. SQL:2003'te pencere fonksiyonlarının tanıtılması ve ROWS BETWEEN çerçeve spesifikasyonu, etkin çalıştırma toplulukları sağlar ve modern olay tabanlı eşzamanlılık hesaplamaları için bir temel oluşturur.
Sorun: Maksimum eşzamanlılık belirlemek, durum değişikliklerinin gerçekleştiği kesin anları anlamayı gerektirir—özellikle bir rezervasyonun başladığı veya bittiği anları. Naif yaklaşım, her aralığı ayrık zaman birimlerine (zaman dilimleme) genişletmektedir ki bu, uzun süreli kalışlar için hesaplama açısından büyük bir yük oluşturur. Temel zorluk, zaman çizelgesinin her anını gerçekleştirmeden, belirli bir noktada ne kadar aralığın örtüşeceğini hesaplamaktır.
Çözüm: Ayrık olay simülasyonu modelini kullanın. Aralık tablosunu UNION ALL kullanarak bir olay akışına dönüştürün, her check-in (başlangıç) için +1 ve her check-out (bitim) için -1 ağırlığı atayın. Bu olayları kronolojik olarak sıralayarak ve SUM() OVER (ORDER BY ...) pencere fonksiyonları ile bir akıcı toplam uygulayarak, her geçiş noktasındaki aktif sayıyı elde edersiniz. Bu akıcı toplamın maksimum değeri tepe eşzamanlılığı temsil eder.
WITH events AS ( SELECT check_in AS event_time, 1 AS delta FROM reservations UNION ALL SELECT check_out AS event_time, -1 AS delta FROM reservations ), concurrency AS ( SELECT event_time, SUM(delta) OVER ( ORDER BY event_time, delta DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS active_count FROM events ) SELECT MAX(active_count) AS peak_concurrency FROM concurrency;
Sorun tanımı: Bir lüks tatil köyü zinciri, tatil hafta sonlarında gizemli aşırı rezervasyon olayları yaşamıştır, bu durum mevcut sistemlerinin boşluk raporlamasına rağmen gerçekleşmiştir. Miras alınan sorgu, her rezervasyonu bireysel gece satırlarına genişleterek günlük doluluğu hesaplamaktaydı ve bu da aylarca süren kalışlar için milyonlarca satır oluşturuyordu. Yeni Yıl Gecesi analizi sırasında, bu yaklaşımın çalışması 12 saniye sürmüş ve rezervasyon işlem tablosunu deadlock yaparak gerçek zamanlı rezervasyonları engellemiştir.
Çözüm A: Zaman dilimi genişletme ile sayım tabloları. Operasyon ekibi başlangıçta bir takvim tablosu önceden oluşturmayı önerdi ve bunu event_date BETWEEN check_in AND check_out kullanarak rezervasyonlarla birleştirdi. Bu yöntem, standart GROUP BY ifadeleri ile uyumlu sezgisel günlük toplamlar sağlar. Artılar: İş analistleri için kavramsal olarak basit, mevcut BI araçlarıyla kolayca entegre edilebilir. Eksiler: O(N × D) satırları oluşturur, burada D ortalama süreyi ifade eder; üstel büyümeye neden olur; dakikalık düzeyde ayrıntıda ya da uzun vadeli kiralamalarda felaketle sonuçlanır; aşırı geçici alan (tempdb) tüketir.
Çözüm B: Materyalize edilmiş yollarla aralık ağacı. Kıdemli bir mimar, aralık sınırlarını indekslemek için iç içe setler kullanarak bir segment ağacı yapısının uygulanmasını önerdi, bu da logaritmik süreli örtüşme sorgularını mümkün kılmaktadır. Artılar: Sık güncellemeler ve nokta sorguları için optimal teorik karmaşıklık. Eksiler: Ağaç dengelemeyi sağlamak için karmaşık tetikleyicilere ihtiyaç duyulması; prosedürel uzantılara dayandığı için ANSI SQL taşınabilirliğini ihlal eder; rezervasyon zirveleri sırasında OLTP yükünü olumsuz etkileyen yazım amplifikasyonu tanıtır.
Çözüm C: Kronolojik olay akışı ile akıcı toplamlar (seçilen). Veritabanı ekibi, her rezervasyon sınırını bir delta işlemi olarak ele alan olay tabanlı yaklaşımı benimsedi. Bu, verisetini patlayan milyonlarca satırdan tam olarak 2N olaya (her rezervasyon için başlangıç ve bitiş) indirdi. Artılar: O(N log N) karmaşıklığı, sıralama işlemi tarafından domine edilir, sabit bir bellek ayak izi ve ANSI SQL uyumluluğu sağlar. Eksiler: Eşit zamanlı olayları dikkatli bir şekilde ele almayı gerektirir ve eklemeler olmadan tepe noktasına katkıda bulunan belirli rezervasyonları tanımlamaz.
Sonuç: Sorgulama gecikmesi 12 saniyeden 45 milisaniyeye düştü. Analiz, gerçek darboğazın oda envanteri (500 birim) değil, asansör kapasitesi olduğunu ortaya koydu, çünkü 320 konuk aynı anda 18:00'da check-in yapmaya çalışıyordu. Bu içgörü, yeni bir kanat inşa etmek yerine, aşamalı check-in kademeleri uygulamayı teşvik etti ve 2 milyon dolarlık sermaye harcaması tasarrufu sağladı, aynı zamanda deadlockları ortadan kaldırdı.
Çözümün neden ORDER BY event_time, delta DESC gerektirdiği ve delta üzerindeki ikincil sıralamayı dışarıda bırakırsanız ne olacağı nedir?
Adaylar, paylaşılan zaman damgalarındaki sınır koşulu anlamını sıklıkla göz ardı eder. Bir konuk tam 10:00'da çıkarken, başka bir konuk da 10:00'da check-in yaparsa, işleme sırası, odanın iki konuk tarafından aynı anda dolu görünüp görünmeyeceğini belirler. delta DESC ile sıralayarak, aynı zaman damgasında -1 (ayrılma) işleminin önce, +1 (gelme) işleminin sonra işlenmesini sağlarız. Bu ikincil sıralama olmadan, akıcı toplam geçici olarak düşer ve sonra sıçrar, bu da önceki durum gerçekte daha yüksekken, hayali bir tepe kaydedebilir. Bu ince sıralama, üretim sistemlerinde aşırı rezervasyon açıklarına yol açan off-by-one hatalarını önler.
Bu sorguyu, tepe eşzamanlılık anında hangi belirli rezervasyonların aktif olduğunu tanımlamak için nasıl değiştirirdiniz, yalnızca sayım değil?
Çoğu aday, aynı CTE içinde filtreleme yapmayı denerken, tepenin devamlı bir aralığı kapsayabileceğini tanımamaktadır. Sağlam bir yaklaşım, iki geçişli bir strateji gerektirir: önce, active_count maksimum değerine eşit olan zaman damgasını bir alt sorgu veya CTE kullanarak ayırmak, ardından r.check_in <= peak.event_time AND r.check_out > peak.event_time örtüşme koşulunu kullanarak orijinal rezervasyon tablosuna geri katılmaktır. Adaylar, birden fazla zaman damgasının aynı maksimum değeri paylaşabileceğini gözden kaçırır; bu, tepe plato birkaç olay geçişi boyunca sürdüğünde, tekrar eden rezervasyon listelemelerini önlemek için bir DISTINCT veya EXISTS ifadesinin gerekliliğini doğurur.
İş kuralları, check-out süresi dâhil olacak şekilde (konuk 23:59'a kadar odayı işgal eder) değişirse ve bu olay ağırlığını nasıl etkiler?
Adaylar, aralık sınırı anlamını çoğunlukla göz ardı eder. Dâhil son noktalar [başlangıç, bitiş], bir rezervasyon bittiğinde ve başka bir rezervasyon başladığında örtüşmelere yol açar. Çözüm, dâhil sınırlarını dışa dönüştürmeyi gerektirir ve bunu yapmanın bir yolu, -1 olayını oluştururken check-out zamanına sonsuz küçük bir epsilon (veya bir sonraki ayrık zaman birimi) eklemektir. Alternatif olarak, akıcı toplam mantığını korurken check_out >= event_time kullanarak birleştirme mantığını ayarlayın. Bu ayarlamayı yapmamak, ayrık olay modelini yarı açık aralıklardan kapalı aralıklara dönüştürerek, algoritmanın hiçbir örtüşme olmadığı yerde çelişkileri raporlamasına ve yüksek devir sürelerinde gerçek kapasiteyi tam olarak birim azaltarak göz önüne almasına neden olur.