SQL Sorguları ile Pandas: Veri Çekme Performansını İyileştirme

Veritabanından milyonlarca satırı Pandas ile çekerken sistem donabiliyor mu? Sorun genellikle tüm veriyi belleğe yüklemeye çalışmaktır. Chunk'lara bölerek, sorguları optimize ederek ve doğru kütüphaneleri kullanarak bu sorunu çöz.

İlk adım: SQLAlchemy ve Pandas'ı birlikte kullan. Veritabanı bağlantısı kur ve sorgunu parçalara ayır.

1import pandas as pd
2from sqlalchemy import create_engine
3
4# Veritabanı bağlantısı
5engine = create_engine('sqlite:///database.db')
6
7# Tüm veriyi bir kez çekme (YAŞLI YÖNTEMİ - yavaş)
8df = pd.read_sql_query('SELECT * FROM orders', engine)
9print(f"Satır sayısı: {len(df)}")

Bu yaklaşım büyük tablolarda bellek taşması yaratır. Çözüm: `chunksize` parametresi ile veriyi parçalı oku.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1# Chunk'lara bölerek okuma (İYİ YÖNTEMİ)
2chunks = []
3for chunk in pd.read_sql_query(
4'SELECT id, amount, date FROM orders WHERE date > "2023-01-01"',
5engine,
6chunksize=10000
7):
8# Her chunk'ı işle
9chunk['amount'] = chunk['amount'].astype(float)
10chunks.append(chunk)
11
12df = pd.concat(chunks, ignore_index=True)
13print(f"Toplam satır: {len(df)}, Bellek kullanımı: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")

Sorguyu da optimize et. Veritabanı tarafında filtreleme yap, gereksiz sütunları dışla.

1# Sorguyu optimize etme
2query = """
3SELECT id, amount, customer_id
4FROM orders
5WHERE status = 'completed'
6AND date >= '2024-01-01'
7ORDER BY id
8LIMIT 1000000
9"""
10
11df = pd.read_sql_query(query, engine, chunksize=50000)
12for chunk in df:
13# İşle
14pass

Ek ipucu: Veritabanında indeks oluştur. `WHERE` ve `JOIN` koşullarında kullanılan sütunlara indeks ekle. Pandas tarafında da kategorik veriler için `category` dtype kullan, bellek tasarrufu %90'a kadar çıkabilir.

1# Kategorik dönüşüm
2df['status'] = df['status'].astype('category')
3df['region'] = df['region'].astype('category')
4print(f"Optimize bellek: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")

Sık yapılan hata: Chunk işlemede her iterasyonda `pd.concat()` çağırmak. Yukarıdaki örnekte olduğu gibi önce listeye topla, sonra bir kez birleştir. Aksi takdirde her ekleme O(n) işlem yapar ve toplam O(n²) zaman alır.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz