- Geçici tablo nedir, hangi sorunu çözer?
- SQL Server'da yerel ve genel geçici tablo
- Tablo değişkeni nedir, geçici tablodan nasıl ayrılır?
- MySQL ve PostgreSQL'de geçici tablo
- Adım adım örnek: dönem sonu müşteri raporu
- Geçici tablo mu, CTE mi, alt sorgu mu?
- Sık yapılan hatalar ve önlemler
- Bu beceriyi Mindset programlarında nerede çalışırsınız?
- Sık sorulan sorular
Geçici tablo kullanımı: karmaşık sorguyu parçalara bölmenin yolu
Geçici tablo ve tablo değişkeni ne zaman gerekir, SQL Server, MySQL ve PostgreSQL'de nasıl kurulur, CTE ile farkı nedir, sık hatalar neler.
Geçici tablo nedir, hangi sorunu çözer?
Geçici tablo, veritabanı sunucusunun yalnızca bir oturum boyunca (bazı sistemlerde bir işlem boyunca) sakladığı tablodur. Kalıcı bir tablodan farkı, işiniz bittiğinde ya da bağlantı kapandığında sunucunun onu kendiliğinden silmesidir. MySQL, PostgreSQL ve SQL Server dokümantasyonları aynı noktada birleşir: yerel geçici tabloyu yalnızca onu oluşturan oturum görür, bu yüzden farklı kullanıcılar aynı adla geçici tablo açsa bile birbirlerinin verisine karışmaz.
Geçici tabloya genellikle bir sorgu çok uzayıp okunmaz hale geldiğinde başvurulur. Örneğin bir raporda önce son dönem siparişlerini süzmeniz, sonra bu sonucu müşteri tablosuyla birleştirmeniz, ardından iade kayıtlarını düşmeniz gerekiyorsa, hepsini tek bir iç içe sorguya sığdırmak yerine ara sonucu geçici bir tabloya yazarsınız. Sonraki adımlar bu küçültülmüş veri üzerinden çalışır. Böylece her adımı ayrı ayrı çalıştırıp sonucunu kontrol edebilirsiniz.
Geçici tablo ayrıca bir ara sonucu aynı betik içinde birden çok kez kullanmanız gerektiğinde işe yarar. Aynı ağır sorguyu birçok yerde yeniden yazmak yerine sonucu bir kez hesaplar, sonra her yerde ondan okursunuz.
SQL Server'da yerel ve genel geçici tablo
SQL Server'da geçici tablo, adın başına konan diyez işaretiyle belirtilir. Tek diyez (#OrderSummary) yerel geçici tablodur: yalnızca oluşturan oturumda görünür ve oturum kapanınca silinir. Çift diyez (##OrderSummary) genel geçici tablodur ve tüm oturumlara görünür; dokümantasyona göre onu kullanan son oturum bitince kaldırılır. Her tür de tempdb adlı sistem veritabanında tutulur.
Temel kalıp şöyledir:
CREATE TABLE #OrderSummary (CustomerNo INT, TotalAmount MONEY); INSERT INTO #OrderSummary (CustomerNo, TotalAmount) SELECT CustomerNo, SUM(Amount) FROM Orders GROUP BY CustomerNo; SELECT * FROM #OrderSummary ORDER BY TotalAmount DESC; DROP TABLE #OrderSummary;
Kısa yoldan, tabloyu önceden tanımlamadan sorgu sonucundan üretmek de mümkündür: SELECT ... INTO #OrderSummary FROM ... biçimi sütun tiplerini sorgudan türetir. Hızlıdır ama sütun tiplerini siz seçmediğiniz için beklenmedik bir tip çıkabilir; kalıcı kullanacağınız betiklerde tabloyu açıkça tanımlamak daha güvenlidir.
Genel geçici tabloyu özel bir gerekçe yoksa kullanmayın. Başka bir oturum aynı adı kullanırsa betikler birbirini bozabilir; yerel geçici tablo bu riski taşımaz.
Tablo değişkeni nedir, geçici tablodan nasıl ayrılır?
Tablo değişkeni, SQL Server'da DECLARE @Liste TABLE (...) biçiminde tanımlanan, kapsamı yalnızca içinde bulunduğu betik grubu, saklı yordam ya da fonksiyonla sınırlı bir tablodur. Geçici tabloya benzer, ama davranışı farklıdır. Ölçüt satırlarıyla karşılaştıralım.
Ölçüt, kapsam: Geçici tablo oturum boyunca yaşar ve iç içe çağrılan yordamlardan da erişilebilir. Tablo değişkeni tanımlandığı blokla biter.
Ölçüt, esneklik: Geçici tabloya sonradan indeks ekleyebilir, ALTER TABLE ile yapısını değiştirebilirsiniz. Tablo değişkeninin yapısı tanımlandığı anda sabitlenir.
Ölçüt, işlem geri alma: Bir işlem geri alındığında (ROLLBACK) geçici tablodaki değişiklikler de geri alınır. Tablo değişkeni ise işlem bütünlüğünden bu açıdan farklı davranır; geri alma sırasında içindeki veriler korunabilir. Bu özellik bazen hata ayıklarken işe yarar.
Ölçüt, istatistik ve plan: Sorgu iyileştirici, geçici tablo için sütun istatistiği tutabilir; tablo değişkeninde bu davranış sürüme göre değişir. Bu yüzden satır sayısı büyüdükçe geçici tablo genellikle daha öngörülebilir plan üretir. Küçük, birkaç satırlık ara listelerde ise tablo değişkeni sade ve yeterli bir seçimdir.
Pratik karar: Az satırlı, tek yerde kullanılacak ara liste için tablo değişkeni; çok satırlı, üzerinde birleştirme ve filtre yapılacak ara sonuç için geçici tablo.
MySQL ve PostgreSQL'de geçici tablo
MySQL'de kalıp CREATE TEMPORARY TABLE adı (...) şeklindedir. MySQL dokümantasyonuna göre bu tablo yalnızca geçerli oturumda görünür ve oturum kapanınca otomatik silinir. Aynı adla kalıcı bir tablo varsa, geçici tablo var olduğu sürece kalıcı olanı gizler; bu, yanlış tabloya yazmaya yol açabilen bir tuzaktır, bu yüzden geçici tablolara ayırt edici bir ad verin.
PostgreSQL'de CREATE TEMPORARY TABLE ya da kısaca CREATE TEMP TABLE kullanılır. Dokümantasyona göre geçici tablolar oturum sonunda silinir; isteğe bağlı olarak ON COMMIT ifadesiyle işlem sonunda satırların silinmesini ya da tablonun düşürülmesini seçebilirsiniz (PRESERVE ROWS, DELETE ROWS, DROP). Bu seçenek, bir işlem içinde ara sonuç tutup işlem bitince temizlik yapmak için pratiktir. PostgreSQL geçici tabloları özel bir şemada tuttuğundan, tablo oluştururken şema adı veremezsiniz.
Sözdizimi sistemden sisteme küçük farklar taşır: SQL Server'da diyez ön eki, MySQL ve PostgreSQL'de TEMPORARY anahtar sözcüğü vardır. Mantık aynı kaldığı için bir sistemde öğrendiğiniz yaklaşımı diğerine kolayca taşırsınız; her seferinde ilgili sürümün dokümantasyonuna bakmak yeterlidir.
Adım adım örnek: dönem sonu müşteri raporu
Örneğin bir perakende şirketinde yönetim, son dönemde en az bir sipariş vermiş ama sonrasında iade yapmamış müşterilerin segment bazında özetini istiyor. Tek bir sorguyla yazarsanız çok katmanlı bir alt sorgu çıkar. Geçici tabloyla akış şöyle kurulur:
- Önce dönem filtresine uyan siparişleri #OrderList adlı geçici tabloya alın. Burada tarih aralığını yalnızca bir kez yazarsınız.
- Ardından iade kayıtlarında geçen müşterileri #Returns tablosuna yazın.
- #OrderList ile #Returns tablolarını LEFT JOIN ile birleştirip iadesi olmayan müşterileri #Clean tablosuna alın.
- Son adımda #Clean tablosunu müşteri-segment tablosuyla birleştirip gruplayın ve raporu üretin.
- Betiğin sonunda geçici tabloları DROP edin ya da oturumun bitmesini bekleyin.
Her ara tabloyu SELECT ile açıp satırlarına bakabildiğiniz için sorunun nerede çıktığı hemen görülür. Tek sorguda bu denetim çok zordur. Bu yöntemin bedeli, ara sonuçların diske yazılması olabilir; veri küçükse fark etmezsiniz, çok büyükse planı gözden geçirmeniz gerekir.
Geçici tablo mu, CTE mi, alt sorgu mu?
Ortak tablo ifadesi (CTE), tek bir sorgu içinde adlandırılmış bir ara sonuç tanımlamanıza izin verir ve okunabilirliği artırır. Ancak CTE yalnızca onu izleyen sorgu boyunca yaşar; sonuç saklanmaz, aynı betikte başka bir sorguda yeniden kullanamazsınız. Geçici tablo ise sonucu gerçekten yazar ve sonraki tüm sorgularda kullanıma açar.
Karar ölçütleri:
- Ara sonuç yalnızca bir sorguda ve bir kez kullanılacaksa CTE ya da alt sorgu yeterlidir.
- Aynı ara sonuç betikte birden çok kez kullanılacaksa ya da üzerine indeks kurmak isterseniz geçici tablo.
- Adımları tek tek gözlemleyip hata ayıklamak istiyorsanız geçici tablo.
- Sorguyu başkalarının da okuyup bakımını yapacağı kalıcı bir yapıya (görünüm, saklı yordam) çevirecekseniz çoğu zaman CTE daha sade kalır.
Bu yaklaşımlar rakip değil, tamamlayıcıdır. Deneyimli sorgu yazarları genellikle önce CTE ile mantığı kurar, performans sorunu görürse ağır adımı geçici tabloya taşır.
Sık yapılan hatalar ve önlemler
- Geçici tabloyu temizlememek. Uzun süren bağlantılarda (uygulama sunucusu havuzları gibi) oturum açık kaldığından tablo da yaşamaya devam eder; aynı adla yeniden oluşturmaya çalışınca hata alırsınız. Betiğin başında tablo varsa düşüren bir koşul kullanın.
- Genel geçici tabloyu ihtiyaç olmadan seçmek. Başka bir oturumla ad çakışmasına yol açar.
- Büyük veri için tablo değişkeni kullanmak. Plan kalitesi bozulabilir; sorguyu gerçek veriyle çalıştırıp yürütme planına bakın.
- Geçici tabloya indeksi hiç düşünmemek. Çok satırlı ara tabloda sık birleştirilen sütuna indeks eklemek sorguyu belirgin biçimde hızlandırabilir.
- Sütun tiplerini SELECT ... INTO ile rastgele bırakmak. Beklenmedik tip, sonraki birleştirmede dönüşüm hatası ya da yavaşlık yaratır.
- Üretim sistemlerinde geçici tabloyu gereksiz yere kullanmak. Sistem veritabanında yük oluşturduğundan, sık çalışan sorgularda önce CTE gibi daha hafif seçenekleri deneyin.
Her durumda ölçmeden kesin hüküm vermeyin: yaklaşımları gerçek veriyle çalıştırıp yürütme süresini ve planı karşılaştırmak en güvenilir yoldur.
Bu beceriyi Mindset programlarında nerede çalışırsınız?
SQL ile Veri Sorgulama (İleri) programının modül başlıkları arasında Ortak Tablo İfadeleri (CTE) ve Recursive Sorgular, Alt Sorgular ve Korelasyon Teknikleri, Sorgu Performansı ve Yürütme Planı Analizi, Görünümler, Stored Procedure ve Tetikleyiciler yer alır. Geçici tablo ile CTE ve alt sorgu arasındaki seçimi yapmak için gereken temel bu başlıklardadır; yürütme planı okumak ise yaklaşımları karşılaştırmanın aracıdır. Rapor yazan analistler ve veritabanı ile çalışan ekipler için uygundur.
SQL ile Programlama Eğitimi ise Veritabanları Oluşturma, Tablolarla Çalışma ve Veri İşleme Dili gibi başlıklarla temeli kurar. Tablo oluşturma ve veri ekleme mantığına yeni olanlar geçici tabloya geçmeden önce bu temeli sağlamlaştırabilir.
İlgili Mindset programı
SQL ile Veri Sorgulama (İleri)
Sık sorulan sorular
Geçici tablo ne zaman silinir?
Yerel geçici tablolar, oluşturan oturum kapandığında otomatik silinir. PostgreSQL'de ON COMMIT seçeneğiyle işlem sonunda satırları silmeyi ya da tabloyu düşürmeyi de seçebilirsiniz. Bağlantı havuzu kullanan uygulamalarda oturum açık kalabildiği için, betiğin sonunda tabloyu açıkça DROP etmek en güvenli alışkanlıktır.
Tablo değişkeni her zaman geçici tablodan daha mı hızlıdır?
Hayır. Az sayıda satırla çalışırken tablo değişkeni hafif ve yeterli olabilir, ama satır sayısı arttığında istatistik ve indeks desteği zayıf kaldığı için plan kalitesi düşebilir. Karar vermeden önce yöntemleri gerçek veriyle çalıştırıp yürütme planını karşılaştırın.
Geçici tabloya indeks eklenebilir mi?
Evet. Geçici tablolara normal tablolar gibi indeks tanımlanabilir. Birleştirme ya da filtrede sık kullanılan sütunlara indeks eklemek, ara sonuç büyükse sorguyu belirgin biçimde hızlandırabilir. Küçük ara tablolarda indeks maliyeti kazancı geçebileceğinden gereksiz yere eklemeyin.
Başka bir kullanıcı benim geçici tablomu görebilir mi?
Yerel geçici tabloyu yalnızca oluşturan oturum görür. Farklı oturumlar aynı adla geçici tablo açsa bile birbirini etkilemez. SQL Server'daki çift diyezli genel geçici tablo bu kuralın istisnasıdır ve tüm oturumlara açıktır; bu yüzden dikkatli kullanılmalıdır.
Geçici tablo yerine hep CTE kullanamaz mıyım?
Çoğu okunabilirlik odaklı işte CTE yeterlidir. Ancak CTE sonucu saklamaz, yalnızca tek sorgu boyunca yaşar. Aynı ara sonucu betikte birkaç kez kullanacaksanız, üzerine indeks kuracaksanız ya da adımları tek tek denetlemek istiyorsanız geçici tablo daha uygundur.