RDMS Sorgularında 20 Performans İpucu


1. İndeksleri Etkili Kullanın

Senaryo: Büyük bir müşteri tablosunda sık sık isim araması yapılıyor. Açıklama: İsim sütununa indeks ekleyerek aramaları hızlandırabilirsiniz.


CREATE INDEX idx_customer_name ON customers(name);

2. EXPLAIN Planını Analiz Edin

Senaryo: Yavaş çalışan bir sorgunuz var ve nedenini anlamak istiyorsunuz. Açıklama: EXPLAIN komutu ile sorgu planını inceleyerek, sorgunun nasıl çalıştığını ve olası darboğazları görebilirsiniz.


EXPLAIN SELECT * FROM orders WHERE customer_id = 1000;

3. Gereksiz Sütunları Seçmekten Kaçının

Senaryo: Tüm ürün bilgilerini çekmek yerine sadece ad ve fiyat bilgisi gerekiyor. Açıklama: SELECT * yerine sadece ihtiyaç duyulan sütunları seçin.


-- Yerine: SELECT name, price FROM products; -- Bundan kaçının: SELECT * FROM products;

4. WHERE Koşullarını Optimize Edin

Senaryo: Tarih aralığında sipariş arama yapılıyor. Açıklama: İndekslenmiş sütunlar üzerinde eşitlik koşulları kullanın ve fonksiyon kullanımından kaçının.


-- İyi: WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31' -- Kötü: WHERE YEAR(order_date) = 2023

5. LIKE Yerine Full-Text Arama Kullanın

Senaryo: Ürün açıklamalarında kelime araması yapılıyor. Açıklama: Büyük metin alanlarında LIKE '%kelime%' yerine full-text arama kullanın.


CREATE FULLTEXT INDEX idx_product_description ON products(description); SELECT * FROM products WHERE MATCH(description) AGAINST('aranan kelime');

6. Geçici Tablolar Yerine CTE Kullanın

Senaryo: Karmaşık bir rapor sorgusu birkaç ara sonuç gerektiriyor. Açıklama: Geçici tablolar yerine CTE (Common Table Expressions) kullanarak sorgu okunabilirliğini ve performansını artırın.


WITH monthly_sales AS ( SELECT DATE_TRUNC('month', order_date) AS month, SUM(total) AS total_sales FROM orders GROUP BY DATE_TRUNC('month', order_date) ) SELECT * FROM monthly_sales WHERE total_sales > 10000;

7. Partition Tabloları Kullanın

Senaryo: Çok büyük bir log tablosunda yıllara göre sorgulama yapılıyor. Açıklama: Tabloyu yıllara göre bölümleyerek (partitioning) sorgu performansını artırın.


CREATE TABLE logs ( id INT, log_date DATE, message TEXT ) PARTITION BY RANGE (EXTRACT(YEAR FROM log_date)); CREATE TABLE logs_2022 PARTITION OF logs FOR VALUES FROM (2022) TO (2023); CREATE TABLE logs_2023 PARTITION OF logs FOR VALUES FROM (2023) TO (2024);

8. Doğru Veri Tiplerini Kullanın

Senaryo: Telefon numaraları için VARCHAR kullanılıyor. Açıklama: Sayısal değerler için uygun sayısal veri tiplerini kullanın. Örneğin, telefon numaraları için BIGINT kullanın.


ALTER TABLE customers ALTER COLUMN phone_number TYPE BIGINT;

9. IN Yerine EXISTS Kullanın

Senaryo: Belirli ürün kategorilerine ait ürünleri listeliyorsunuz. Açıklama: Büyük listelerde IN yerine EXISTS kullanmak daha performanslı olabilir.


-- Yerine: SELECT * FROM products p WHERE EXISTS (SELECT 1 FROM categories c WHERE c.id = p.category_id AND c.name IN ('Electronics', 'Books')); -- Bundan kaçının: SELECT * FROM products WHERE category_id IN (SELECT id FROM categories WHERE name IN ('Electronics', 'Books'));

10. Düzenli İstatistik Güncellemeleri Yapın

Senaryo: Sorgu planlayıcısı optimal planı üretmiyor. Açıklama: Veritabanı istatistiklerini düzenli olarak güncelleyerek sorgu planlayıcısının daha iyi kararlar vermesini sağlayın.


ANALYZE customers;




11. Birleştirme (JOIN) İşlemlerini Optimize Edin

Senaryo: Çok sayıda tabloyu birleştiren karmaşık bir sorgunuz var. Açıklama: Birleştirme sırasını optimize edin, en küçük sonuç kümesini üreten tabloları önce birleştirin.


SELECT c.name, o.order_date, p.product_name FROM customers c JOIN orders o ON c.id = o.customer_id JOIN order_items oi ON o.id = oi.order_id JOIN products p ON oi.product_id = p.id WHERE c.country = 'USA'

12. Gereksiz Alt Sorguları Ortadan Kaldırın

Senaryo: Her müşterinin en son siparişini bulmak için alt sorgu kullanılıyor. Açıklama: Alt sorgu yerine analitik fonksiyonlar kullanarak performansı artırın.


-- Yerine: SELECT customer_id, order_date, total FROM ( SELECT customer_id, order_date, total, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) as rn FROM orders ) sub WHERE rn = 1; -- Bundan kaçının: SELECT customer_id, order_date, total FROM orders o1 WHERE order_date = ( SELECT MAX(order_date) FROM orders o2 WHERE o2.customer_id = o1.customer_id );

13. İndeks Taraması Yerine Tablo Taramasından Kaçının

Senaryo: Büyük bir tabloda belirli bir koşulu sağlayan az sayıda satır aranıyor. Açıklama: Uygun indeksler oluşturarak tablo taramasını önleyin.


CREATE INDEX idx_orders_status ON orders(status); SELECT * FROM orders WHERE status = 'shipped';

14. UNION ALL ve UNION'u Doğru Kullanın

Senaryo: İki farklı sorgu sonucunu birleştirmeniz gerekiyor. Açıklama: Tekrar eden satırları elemeniz gerekmiyorsa, UNION yerine UNION ALL kullanın.


-- Daha hızlı (tekrar eden satırları elemez): SELECT product_id FROM order_items UNION ALL SELECT product_id FROM cart_items; -- Daha yavaş (tekrar eden satırları eler): SELECT product_id FROM order_items UNION SELECT product_id FROM cart_items;

15. Gereksiz Koşulları Kaldırın

Senaryo: WHERE yan tümcesinde gereksiz veya tekrar eden koşullar var. Açıklama: Mantıksal olarak eşdeğer olan daha basit koşullar kullanın.


-- Yerine: WHERE status = 'active' AND (age >= 18 AND age <= 65) -- Bundan kaçının: WHERE status = 'active' AND age >= 18 AND age <= 65 AND status != 'inactive'

16. Sayfalama (Pagination) Kullanın

Senaryo: Büyük bir sonuç kümesinin tamamını bir kerede çekiyorsunuz. Açıklama: LIMIT ve OFFSET kullanarak sonuçları sayfalara bölün.


SELECT * FROM products ORDER BY name LIMIT 20 OFFSET 40; -- 3. sayfa, sayfa başına 20 ürün

17. Koşullu Toplama İşlemlerini Optimize Edin

Senaryo: Farklı durumlar için ayrı ayrı toplama yapmanız gerekiyor. Açıklama: Çoklu CASE ifadeleri ile tek bir tarama yapın.


SELECT SUM(CASE WHEN status = 'completed' THEN total ELSE 0 END) as completed_total, SUM(CASE WHEN status = 'pending' THEN total ELSE 0 END) as pending_total FROM orders;

18. Önyükleme (Prefetching) Kullanın

Senaryo: Bir uygulamada, ilişkili verileri ayrı sorgularla çekiyorsunuz. Açıklama: İlişkili verileri tek bir sorguda önceden yükleyin.


SELECT o.*, c.name as customer_name, c.email as customer_email FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'processing';

19. Geçici İndeksler Kullanın

Senaryo: Nadiren çalıştırılan ama yoğun işlem gerektiren bir raporlama sorgunuz var. Açıklama: Sorgu öncesinde geçici indeks oluşturup, sorgu sonrasında silin.


CREATE INDEX tmp_idx_order_date ON orders(order_date); -- Raporlama sorgusunu çalıştır DROP INDEX tmp_idx_order_date;

20. Dış Anahtarları (Foreign Keys) Akıllıca Kullanın

Senaryo: Çok sayıda ilişkili tablo var ve veri bütünlüğünü korumak istiyorsunuz. Açıklama: Dış anahtarlar veri bütünlüğünü sağlar ancak performansı etkileyebilir. Gerektiğinde uygulama seviyesinde kontroller yapın.


ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customers(id);

Please Select Embedded Mode To Show The Comment System.*

Daha yeni Daha eski

نموذج الاتصال