• 29.10.2026 11:13:42
  • İbrahim Gökyar

Deneyimli geliştiriciler için pratik veritabanı eğitimi: ölçüm, database indexleme kararları, SQL/NoSQL profil yöntemleri ve konkre uygulamalarla veritabanı optimizasyonu adımları.

Veritabanı Performans Ayarlama: İndeks, Plan ve Bellek Ayarları Kılavuzu

Veritabanı optimizasyonu: Ölçüm, baseline ve yeniden üretilebilir benchmark

Optimizasyona baslamadan once 'tekrar edilebilir' bir baseline almak zorunlu. PostgreSQL icin somut adim: pgbench ile is yukunu olusturup, EXPLAIN (ANALYZE, BUFFERS) ile tek sorgu profilini kaydedin. Ornek komutlar:

# baseline single-query profile (psql)
psql -c "EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 12345;"
# load-style benchmark (pgbench)
pgbench -c 10 -j 2 -T 60 -S yourdb
Bu ciktilardan sonra medyan ve 95. persentil icin pgbench -r opciyonuyla su sekilde karsilastirma yapin:
pgbench -c 20 -T 120 -r -S yourdb > before.txt
# degisikligi uygulayin
pgbench -c 20 -T 120 -r -S yourdb > after.txt
# sonra 'latency' kolonlarini ayiklayip medyan/95 hesaplayin, veya Python ile pandas kullanin
Bu yontem sayesinde once-sonra karsilastirmasi sayisal olarak tutarli olacaktir.

SQL Server icin benzer baseline alma: SET STATISTICS IO, TIME ON ile sorgu maliyetini alin, oncesinde plan cache ve buffer temizlemek icin

DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT ...;
adimlarini kullani; sonrasinda ayni is yukunu tekrar calistirip carpraz karsilastirma yap. Onemli: her testte donemsel etkilerden kurtulmak icin pipeline ile 3-5 tekrar al, medyan kuçuk haric sapmalari gosterecektir.

Neden bu kadar titiziz: planda ufak bir degisiklik (index create, work_mem artisi, join order) I/O patterns i degistirir; ancak tek bir tek deneme ekonomik degildir. Tekrar edilebilir benchmark ile etkisi I/O sayisi, page cache hit ratio ve CPU time bazinda sayisal olarak gorebilirsiniz: EXPLAIN BUFFERS size heap_blocks_hit, heap_blocks_read gibi metrikler verir.

Database indexleme: Indeks tipi, covering index ve index-only scan incelikleri

Database indexleme kararini veri dağılımina ve sorgu kaligina gore vermelisiniz. PostgreSQL ornegi: bir SELECT listesinde sükünle fetch edilen kolonlar icin CREATE INDEX ... INCLUDE ile covering index olusturmak sorguyu index-only scan'e cevirebilir. Somut ornek:

-- PostgreSQL covering index
CREATE INDEX CONCURRENTLY ix_orders_customer_date ON orders (customer_id, order_date) INCLUDE (total_amount);
-- kontrol: index tarama istatistigi
SELECT indexrelid::regclass AS index_name, idx_scan FROM pg_stat_all_indexes WHERE schemaname = 'public' AND indexrelid::regclass::text LIKE 'ix_orders_%';

Index-only scan basarisi icin visibility map ve vacuum onemlidir: index-only scan ancak ilgili tuple'larin visibility map'te 'all-visible' isareti varsa calisir. Kontrol icin:

-- visibility map oranini tahmini olarak gorme
SELECT relname, 100.0 * heap_blks_hit / NULLIF(heap_blks_read + heap_blks_hit,0) AS cache_hit_pct
FROM pg_statio_user_tables WHERE relname = 'orders';
-- vacuum ve analyze ornegi
VACUUM (VERBOSE, ANALYZE) orders;
Vacuum yapmadan index-only scan beklemeyin: plan index-only olarak ciksa bile visibility yoksa heap fetch gerceklesir.

SQL Server icin benzer davranis: covering index icin INCLUDE kullanin ve index bloat veya fragmentation i sys.dm_db_index_physical_stats ile takip edin:

SELECT avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('dbo.Orders'), NULL, NULL, 'LIMITED');
CREATE NONCLUSTERED INDEX IX_Orders_Cust_Date ON dbo.Orders(customer_id, order_date) INCLUDE (total_amount);
Fragmentation yuksekse ALTER INDEX ... REORGANIZE/REBUILD ile duzeltin ve oncesi-sonrasi page_count/fragmentation degerlerini kaydedin.

Edge case: multikey veya array indexleri (Postgres GIN) cok faydali olabilir ama update write-amplification ve index size artisi getirir. Bu durumda task: olasi sorgular icin partial index veya expression index kullanarak sarti daraltin:

CREATE INDEX CONCURRENTLY ix_orders_active_customer ON orders(customer_id) WHERE status = 'active';

Veritabanı performans ayarlama: Bellek ayarlari (work_mem, maintenance_work_mem) ve etkileri

Sorgu planlarinin disk-spill yapma sebebi genellikle yetersiz bellek ayarlari. PostgreSQL icin concret adim: sorgu oncesi EXPLAIN ANALYZE ile 'Disk' yasanip yasanmadigini kontrol edin; sonra work_mem'i mantikli bir deger ile artirin ve yeniden test edin:

-- on-the-fly test
SET work_mem = '64MB';
EXPLAIN (ANALYZE, BUFFERS) SELECT ... GROUP BY ...;
-- kalici olarak ayarla
ALTER SYSTEM SET work_mem = '32MB';
SELECT pg_reload_conf();
Profiling araci: EXPLAIN (ANALYZE, BUFFERS) ciktilarindaki '-> Sort' ve '-> Hash' node'lari altinda 'Disk' ibaresi arayin. Once/sonra karsilastirmasini sayisal yapin: heap_blocks_read ve shared_blks_read farklari, CPU time ve execution time.

SQL Server tarafinda ise bellek grant issue'larini sys.dm_exec_query_memory_grants ile tespit edin:

SELECT grant_time, requested_memory_kb, granted_memory_kb, query_plan
FROM sys.dm_exec_query_memory_grants
WHERE requested_memory_kb > 0;
Belirli bir sorgu icin OPTION (MAXDOP 1, FORCE ORDER) denemeleri yaparken memory grant ihtiyacinin nasil degistigini DBCC MEMORYSTATUS yerine gecici testler ile olcmek icin workload tekrarlayin.

Neden: work_mem arttirdiginizda sort/hash operatorleri bellege dortur ve spill IO'su azalir; bu I/O ile gecen yavaslamayi ortadan kaldirir. Ancak gereksiz buyuk work_mem her baglanti icin ayrilabileceginden aktif baglanti sayisini multiplike ettiginizde toplam bellek baskisi olusur. Bu yuzden profiling icin 'per-connection' worst-case senaryolarini da pgbench ile test edin:

pgbench -c 100 -T 60 -j 10 -f heavy_work_mem_test.sql yourdb

SQL eğitimi ve SQL Server eğitimi: Parametre sniffing, plan caching ve on-the-fly fixes

Parametre sniffing problemleri hem SQL Server hem de PostgreSQL prepared statement'larda gorulebilir. SQL Server icin somut cozum: sorguya OPTION (RECOMPILE) veya local temporary table ile istatistik cheat yapin. Ornek:

CREATE PROCEDURE dbo.GetOrders @cust INT
AS
SELECT * FROM dbo.Orders WHERE customer_id = @cust
OPTION (RECOMPILE);
Ancak OPTION (RECOMPILE) CPU maliyeti artirir; onemli olan sayisal profil: oncesi cached plan kullanimi, sonra recompile ile gecen zaman farkini sys.dm_exec_cached_plans ve Query Store olmadan sys.dm_exec_query_stats ile olcmelisiniz.

PostgreSQL tarafinda benzer sorunlar prepared statement'larin generic plan'a donmesiyle ortaya cikabilir. Onu tespit icin:

-- onerilen tespit
EXPLAIN (ANALYZE, BUFFERS) EXECUTE my_prepared_stmt(123);
-- alternatif: dinamik SQL ile planin sabitlenmesini saglayin
PREPARE ps (int) AS SELECT * FROM orders WHERE customer_id = $1;
EXECUTE ps(123);
Cozumler: plan parametre adaptasyonu icin explicit query rewrite, ornekleyici hint'ler veya client tarafli plan caching stratejileri kullanin.

Edge case: bazen 'small selective value' icin index scan, 'broad value' icin seq scan daha iyidir; optimizer beklediginden farkli frekans gordugunde plan gerilemesi olur. Bunu onlemek icin istatistik histogramlarinizi donemsel olarak guncelleyin:

ANALYZE VERBOSE orders;
-- PostgreSQL extended statistics ornek
CREATE STATISTICS st_on_customer (ndistinct, dependencies) ON (customer_id, status) FROM orders;
ANALYZE orders;

NoSQL eğitimi: MongoDB indexleme, explain ve write amplification onlemleri

NoSQL veri tabanlarinda da indeks kararlari performans icin kritiktir. MongoDB ornegi: sorgu profilini almak icin mongosh'da explain('executionStats') kullanin ve mongostat ile sunucu istatistiklerini izleyin. Somut ornek komutlar:

-- index olusturma
db.orders.createIndex({customer_id: 1, order_date: -1}, {background: true});
-- sorgu profili
db.orders.find({customer_id: 12345}).sort({order_date: -1}).explain('executionStats');
-- mongostat ve mongotop izleme
mongostat --host mongodb0.example.net:27017 1
mongotop 1

Multikey indexler ve array alanlar write-amplification'a yol açabilir; bunun etkisini doğrulamak icin indexSize ve collection size'ini db.collection.stats() ile karsilastirin:

db.orders.stats();
db.collection.getIndexes();
Eger indexler gereksiz buyukse partial index veya TTL index kullanarak index islemlerini kisitin.

Neden: NoSQL motorlari farklı storage engine kurallariyla calisir (WiredTiger vs muhtemel baska engine'ler): page compression, checkpoint frekansi ve lock granularity indeks davranisini dogrudan etkiler. Bu nedenle mongod.conf degisiklikleri (wiredTiger.engineConfig.cacheSizeGB gibi) uygularken oncesinde mongostat toplu benchmark alin ve sonra karsilastirin.

Izleme, otomasyon ve onarim: pg_stat_statements, Prometheus ve otomatik alert playbook

Sistem surekli izlenmezse optimizasyonlar etkisini kaybeder. PostgreSQL icin somut kurulum:

-- extension kur ve en populer sorgulari cek
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls, total_time, mean_time FROM pg_stat_statements ORDER BY total_time DESC LIMIT 20;
Bu ciktilari Prometheus exporter (postgres_exporter) ile toplayip Grafana'da dashboard ve alert rule haline getirin. Ornek Prometheus kural: latency 95th > 500ms icin uyar.

Otomasyon playbook ornegi: kritik bir sorgunun 95p latencysi arttiginda otomatik olarak work_mem veya index rebuild tetiklemek genellikle risklidir. Iyi bir akis: alert -> insan onayi -> runbook script calistir. Runbook kisa bir bash onarimi icin:

# runbook example: rebuild index safely
psql -c "REINDEX INDEX CONCURRENTLY ix_orders_customer_date;"
# veya SQL Server icin
ALTER INDEX IX_Orders_Cust_Date ON dbo.Orders REBUILD WITH (ONLINE = ON);

Edge case: otomatik index olusturma araclari bazen gereksiz index uretebilir; onlari once 'staging' ortaminda pgbench ile test edin, sonra production'a uygulatin. Izleme metrikleri olarak sadece latency degil, heap_blks_read, shared_blks_hit, page_faults ve CPU utilisation da takip edilmeli.

Sık Sorulan Sorular

veritabanı optimizasyonu yapmak icin hangi profiling aracini oncelikle kullanmaliyim?

Ilk adim olarak sorgu-level profiling icin PostgreSQL'de EXPLAIN (ANALYZE, BUFFERS) ve pg_stat_statements, SQL Server'da SET STATISTICS IO/TIME ve sys.dm_exec_query_stats kullanin. Sayisal karsilastirma icin once pgbench veya benzer load tool ile baseline alin, sonra degisikligi uygulayip tekrar calistirin ve medyan ile 95. persentil farkini karsilastirin.

database indexleme kararini verirken nelere dikkat etmeliyim, hangi SQL komutlari isime yarar?

Indeks kararinda sorgu selectivity, update frekansi ve hangi kolonlarin select/projection icinde oldugu onemli. PostgreSQL icin CREATE INDEX ... INCLUDE veya partial index, SQL Server icin CREATE NONCLUSTERED INDEX ... INCLUDE kullanin. Kontrol icin pg_stat_all_indexes veya sys.dm_db_index_physical_stats sorgularini calistin.

nosql eğitimi icerisinde MongoDB'de index boyutunu ve write amplification'i nasil olcerim?

MongoDB'de db.collection.stats() ile indexSize ve storageSize degerlerini kontrol edin, mongostat ile write throughput'u izleyin. Sorgu profillemek icin db.collection.explain('executionStats') kullanin. Buyuk indexler ve multikey indexler write-amplification'a neden oluyorsa partial index veya TTL ile azaltma deneyin.

sql server eğitimi kacirmadan parametre sniffing problemini nasil cozerim?

On-the-fly cozumler: sorguya OPTION (RECOMPILE) eklemek veya sorguyu local temp table ile yeniden yazarak planin degismesini saglamak. Problemi onermek icin sys.dm_exec_cached_plans ve sys.dm_exec_query_stats ile hangi planin hangi parametreyle olusturuldugunu tespit edip test workload ile re-run yapin.

AI / LLM Discovery

Bu makale Opendart Akademi Veritabanı eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.

Opendart Akademi llms.txt