<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Haktan Oktay</title>
    <description>The latest articles on DEV Community by Haktan Oktay (@oktayhaktan0).</description>
    <link>https://dev.to/oktayhaktan0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4034490%2Faf8ebffe-9042-4991-9252-5abd8d7d7c79.png</url>
      <title>DEV Community: Haktan Oktay</title>
      <link>https://dev.to/oktayhaktan0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oktayhaktan0"/>
    <language>en</language>
    <item>
      <title>PostgreSQL'de Yavaş Sorguları EXPLAIN ANALYZE ile Çözmek</title>
      <dc:creator>Haktan Oktay</dc:creator>
      <pubDate>Sat, 18 Jul 2026 11:52:14 +0000</pubDate>
      <link>https://dev.to/oktayhaktan0/postgresqlde-yavas-sorgulari-explain-analyze-ile-cozmek-2eol</link>
      <guid>https://dev.to/oktayhaktan0/postgresqlde-yavas-sorgulari-explain-analyze-ile-cozmek-2eol</guid>
      <description>&lt;p&gt;PostgreSQL'de bir sorgu yavaşladığında ilk refleks rastgele indeks eklemek olmamalı. Önce veritabanının sorguyu nasıl çalıştırdığını görmeli, ardından ölçüme dayalı bir değişiklik yapmalıyız.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bu yazı, &lt;a href="https://haktanoktay.com/blog/postgresql-explain-analyze-indeks-rehberi" rel="noopener noreferrer"&gt;PostgreSQL EXPLAIN ANALYZE ve doğru indeks tasarımı rehberinin&lt;/a&gt; kısa ve uygulanabilir özetidir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  EXPLAIN ile EXPLAIN ANALYZE arasındaki fark
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;EXPLAIN&lt;/code&gt;, PostgreSQL'in seçtiği sorgu planını tahmini maliyetlerle gösterir. &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; ise sorguyu gerçekten çalıştırır ve her adımın gerçek süresini, dönen satır sayısını ve tekrar sayısını raporlar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ANALYZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUFFERS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;125&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;CURRENT_DATE&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'90 days'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;BUFFERS&lt;/code&gt; seçeneği özellikle değerlidir. Sorgunun veriyi bellekten mi yoksa diskten mi okuduğunu görmenizi sağlar. Aynı sorgu test ortamında hızlı, üretimde yavaşsa farkın kaynağı çoğu zaman veri hacmi ve disk erişimidir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planda önce hangi alanlara bakılmalı?
&lt;/h2&gt;

&lt;p&gt;Bir sorgu planını incelerken şu dört sinyal çoğu problemi ortaya çıkarır:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actual time:&lt;/strong&gt; Operatörün gerçekten ne kadar sürdüğünü gösterir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rows:&lt;/strong&gt; Tahmin edilen ve gerçek satır sayıları arasındaki büyük fark istatistik sorununa işaret edebilir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loops:&lt;/strong&gt; Bir adımın kaç kez tekrarlandığını gösterir. Küçük görünen maliyet binlerce tekrar sonunda pahalı olabilir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buffers:&lt;/strong&gt; Okunan veya önbellekten kullanılan sayfa miktarını gösterir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Örneğin plan milyonlarca satır üzerinde &lt;code&gt;Seq Scan&lt;/code&gt; gösteriyorsa bu mutlaka hata değildir. Tablo küçükse veya sorgu satırların büyük bölümünü istiyorsa sıralı tarama doğru seçim olabilir. Kararı operatör adına göre değil, gerçek süre ve okunan satır miktarına göre vermek gerekir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doğru indeks nasıl seçilir?
&lt;/h2&gt;

&lt;p&gt;İndeks, sorgunun filtreleme ve sıralama biçimine göre tasarlanmalıdır. Yukarıdaki sorgu için aşağıdaki bileşik indeks iyi bir başlangıçtır:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;CONCURRENTLY&lt;/span&gt; &lt;span class="n"&gt;idx_orders_customer_created&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Burada eşitlik filtresi kullanılan &lt;code&gt;customer_id&lt;/code&gt; önce, tarih aralığı ve sıralamada kullanılan &lt;code&gt;created_at&lt;/code&gt; sonra gelir. &lt;code&gt;CONCURRENTLY&lt;/code&gt; üretim ortamında yazma işlemlerini uzun süre kilitlemeden indeks oluşturmayı sağlar; ancak işlem daha uzun sürer ve transaction bloğu içinde çalıştırılamaz.&lt;/p&gt;

&lt;p&gt;Her sorgu için yeni indeks eklemek de doğru değildir. Fazla indeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;INSERT ve UPDATE işlemlerini yavaşlatır,&lt;/li&gt;
&lt;li&gt;disk kullanımını artırır,&lt;/li&gt;
&lt;li&gt;bakım ve vacuum maliyetini yükseltir,&lt;/li&gt;
&lt;li&gt;sorgu planlayıcısının seçeneklerini gereksiz yere çoğaltır.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tahminler neden bozulur?
&lt;/h2&gt;

&lt;p&gt;Plan üzerinde tahmini satır sayısı ile gerçek satır sayısı arasında büyük fark varsa önce istatistikleri yenileyin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ANALYZE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dağılımı dengesiz kolonlarda varsayılan istatistik hedefi yetersiz kalabilir. Böyle durumlarda kolon bazında hedef yükseltilebilir; fakat bunu ölçmeden sistem genelinde artırmak gereksiz bakım yükü oluşturur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uygulanabilir kontrol listesi
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Problemi gerçek parametrelerle yeniden üretin.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EXPLAIN (ANALYZE, BUFFERS)&lt;/code&gt; çıktısını alın.&lt;/li&gt;
&lt;li&gt;En çok süre harcayan operatörü bulun.&lt;/li&gt;
&lt;li&gt;Tahmini ve gerçek satır sayılarını karşılaştırın.&lt;/li&gt;
&lt;li&gt;Mevcut indeksleri ve indeks kullanımını kontrol edin.&lt;/li&gt;
&lt;li&gt;Tek bir değişiklik yapın ve aynı sorguyu yeniden ölçün.&lt;/li&gt;
&lt;li&gt;İyileştirmenin yazma maliyetine etkisini izleyin.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Performans optimizasyonunun özü budur: tahmin etmek yerine ölçmek, tek değişkeni değiştirmek ve sonucu tekrar ölçmek.&lt;/p&gt;

&lt;p&gt;Kurumsal bir API veya yoğun veri kullanan uygulamada sorgu performansı, önbellekleme ve veri modeli birlikte ele alınmalıdır. Bu tür bir sistem için &lt;a href="https://haktanoktay.com/api-backend-gelistirme/" rel="noopener noreferrer"&gt;API ve backend geliştirme yaklaşımımı&lt;/a&gt; inceleyebilir veya &lt;a href="https://haktanoktay.com/blog/postgresql-explain-analyze-indeks-rehberi" rel="noopener noreferrer"&gt;orijinal PostgreSQL rehberinin tamamını&lt;/a&gt; okuyabilirsiniz.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>performance</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
