WordPress Siteleri İçin MySQL EXPLAIN Planını Anlamak ve Okumak
WordPress sitelerinin performansı, büyük ölçüde altında yatan MySQL veritabanının verimli çalışmasına bağlıdır. Yavaş yüklenen sayfalar, takılan yönetici panelleri veya zaman aşımına uğrayan sorgular, genellikle kötü optimize edilmiş veritabanı sorgularının bir sonucudur. İşte tam bu noktada MySQL’in EXPLAIN komutu devreye girer. Bu makale, EXPLAIN çıktısını nasıl okuyacağınızı, yorumlayacağınızı ve WordPress sitenizin veritabanı performansını artırmak için nasıl kullanacağınızı adım adım açıklayacaktır.
EXPLAIN Nedir ve Neden Önemlidir?
EXPLAIN, MySQL’in bir sorguyu nasıl yürüteceğini gösteren bir araçtır. Bir sorguyu çalıştırmadan önce, veritabanı motorunun o sorguyu hangi yollarla işleyeceğini, hangi indeksleri kullanacağını, kaç satır okuyacağını ve olası performans darboğazlarını görselleştirmemizi sağlar. WordPress gibi dinamik ve veritabanı yoğun uygulamalar için EXPLAIN çıktısını anlamak, performans optimizasyonunda kritik bir adımdır.
Performans Sorunlarını Teşhis Etme
EXPLAIN olmadan, bir sorgunun neden yavaş çalıştığını anlamak oldukça zordur. Çıktı, sorgunun hangi aşamasının zaman aldığını, gereksiz taramalar yapıp yapmadığını veya doğru indeksleri kullanıp kullanmadığını göstererek, sorunun kök nedenini bulmanıza yardımcı olur. Bu sayede, “deneme yanılma” yönteminden kurtulup, doğrudan sorunu çözmeye odaklanabilirsiniz.
WordPress Bağlamında EXPLAIN
WordPress, wp_posts, wp_postmeta, wp_options, wp_users, wp_termmeta, wp_terms, wp_term_relationships ve wp_term_taxonomy gibi birçok tabloyu yoğun bir şekilde kullanır. Eklentiler ve temalar da kendi özel tablolarını ekleyebilir. Bu tablolar üzerindeki sorgular, sitenizin hızını doğrudan etkiler. EXPLAIN kullanarak, popüler eklentilerin veya temanızın oluşturduğu karmaşık sorguların performansını analiz edebilir ve iyileştirme potansiyeli olan alanları belirleyebilirsiniz.
EXPLAIN Nasıl Kullanılır? (Temel Sözdizimi)
EXPLAIN komutunu kullanmak oldukça basittir. Optimize etmek istediğiniz herhangi bir SELECT, INSERT, UPDATE veya DELETE sorgusunun başına EXPLAIN anahtar kelimesini eklemeniz yeterlidir.
EXPLAIN SELECT * FROM wp_posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date DESC LIMIT 10;
Bu komut, sorguyu çalıştırmaz, sadece MySQL'in bu sorguyu nasıl yürüteceğine dair bir plan sunar.
EXPLAIN Çıktısının Temel Sütunları
EXPLAIN çıktısı, her bir sorgu bölümü için bir satır içeren bir tablo şeklinde sunulur. Her sütun, sorgunun yürütme planının belirli bir yönünü açıklar. İşte en önemli sütunlar ve anlamları:
id, select_type, table
id: Sorgu içindeki SELECT ifadelerinin sırasını gösterir. Aynıiddeğerine sahip satırlar, sorgunun aynı aşamasında yürütülen bölümleri temsil eder.select_type: SELECT sorgusunun tipini belirtir. Önemli tipler şunlardır:SIMPLE: Basit bir SELECT sorgusu (JOIN veya alt sorgu yok).PRIMARY: En dıştaki SELECT (JOIN'ler varsa).SUBQUERY: Bir alt sorgudaki ilk SELECT.DERIVED: Bir FROM maddesindeki alt sorgunun sonucu (geçici tablo oluşturulur).UNION: Bir UNION içindeki ikinci veya sonraki SELECT.DEPENDENT SUBQUERY: Dış sorguya bağımlı bir alt sorgu.
table: Sorgunun çalıştığı tablo adını gösterir. Geçici tablolar veya türetilmiş tablolar için de özel isimler görünebilir.
type (En Kritik Sütun)
type sütunu, MySQL'in tablodaki satırları nasıl bulduğunu gösterir ve sorgu performansının en önemli göstergelerinden biridir. Değerler, en iyiden en kötüye doğru sıralanır:
system > const > eq_ref > ref > range > index > ALL
Bu tipleri daha detaylı inceleyeceğiz.
possible_keys, key, key_len
possible_keys: MySQL'in sorguyu hızlandırmak için kullanabileceği olası indeksleri listeler.key: MySQL'in sorguyu yürütmek için aslında seçtiği indeksi gösterir. EğerNULLise, hiçbir indeks kullanılmamıştır.key_len: MySQL'in seçilen indeksi kullanırken kaç bayt kullandığını gösterir. Bu, bileşik indekslerde hangi sütunların kullanıldığını anlamak için faydalıdır.
ref, rows, filtered
ref:keytarafından belirtilen indeksle karşılaştırılan sütunları veya sabitleri gösterir. Genellikleconstveya bir tablo adı ve sütun adı içerir.rows: MySQL'in sorguyu tamamlamak için taramayı tahmin ettiği satır sayısını gösterir. Bu değer ne kadar düşükse, sorgu o kadar verimlidir.filtered: Tablo satırlarının tahmini yüzdesini gösterir ki bu satırlar, bir sonraki tabloya veya istemciye gönderilmeden önce tablo koşullarıyla filtrelenecektir. Yüksek birfiltereddeğeri, MySQL'in çok fazla satırı okuyup sonra filtrelediğini gösterir.
Extra (Ek Bilgiler)
Extra sütunu, MySQL'in sorgu yürütme hakkında ek bilgiler sağladığı kritik bir alandır. Burada görünen bazı ifadeler, ciddi performans sorunlarının göstergesi olabilir.
type Sütununu Anlamak: Performansın Kalbi
type sütunu, bir sorgunun ne kadar iyi optimize edildiğini anlamak için en önemli göstergedir. İşte farklı type değerleri ve anlamları:
system, const, eq_ref (İdeal Tipler)
system: Tabloda sadece bir satır varsa (bir sistem tablosu gibi). Bu en hızlı tiptir.const: Sorgu sabit bir değerle eşleşen tek bir satırı okuduğunda kullanılır. Genellikle birincil anahtar veya benzersiz bir indeks kullanıldığında ortaya çıkar. Çok hızlıdır.eq_ref: JOIN'lerde, önceki tablodan gelen her satır için geçerli tablodan sadece bir satır okunduğunda kullanılır. Birincil anahtar veya benzersiz indeks üzerinde bir JOIN olduğunda görülür. Çok iyidir.
ref, range (İyi Tipler)
ref: Bir indeks kullanılarak eşleşen tüm satırları bulur.eq_ref'ten farklı olarak, birden fazla satır eşleşebilir. Birincil anahtar veya benzersiz olmayan indeksler üzerinde kullanılır. İyi bir performanstır.range: Belirli bir aralıktaki satırları almak için bir indeks kullandığında kullanılır (örneğin,WHERE id BETWEEN 10 AND 20veyaWHERE post_date > '2023-01-01'). İyi bir performanstır.
index, ALL (Kaçınılması Gereken Tipler)
index: MySQL, indeksin tamamını tarayarak sorguyu yürütür. Bu,ALL'dan daha iyidir çünkü veri dosyası yerine indeks dosyası taranır, bu da genellikle daha küçüktür. Ancak yine de tüm indeksi taramak maliyetlidir.ORDER BYveyaGROUP BYgibi durumlarda, indeks sıralamasını kullanmak için görülebilir.ALL: MySQL, sorguyu tamamlamak için tablonun tamamını tarar. Bu, en kötü performans göstergesidir ve büyük tablolar için kesinlikle kaçınılmalıdır. Genellikle uygun indekslerin eksikliğinden kaynaklanır.
Diğer Tipler
fulltext: FULLTEXT indeksleri kullanıldığında.ref_or_null:refgibi, ancakNULLdeğerlerini de içerir.unique_subquery,index_subquery,index_merge: Daha karmaşık alt sorgu veya indeks birleştirme senaryolarında görülür.
Extra Sütunundaki Kritik İfadeler
Extra sütunu, sorgu optimizasyonunda önemli ipuçları sunar. Bazı ifadeler, sorgunuzun ciddi şekilde optimize edilmesi gerektiğini gösterir.
Using filesort
Bu ifade, MySQL'in sonuçları sıralamak için geçici bir dosya veya bellek alanı kullanması gerektiği anlamına gelir. Bu, özellikle büyük veri kümelerinde çok yavaş olabilir. Genellikle ORDER BY veya GROUP BY ifadeleri için uygun bir indeksin olmamasından kaynaklanır. Bu ifadeyi gördüğünüzde, sıralama için bir indeks eklemeyi düşünmelisiniz.
Using temporary
MySQL'in sorguyu işlemek için geçici bir tablo oluşturması gerektiği anlamına gelir. Bu, genellikle GROUP BY veya DISTINCT işlemleriyle birleşen ORDER BY ifadelerinde veya karmaşık JOIN'lerde görülür. Geçici tablolar diskte oluşturulursa çok yavaş olabilir. Mümkün olduğunca kaçınılmalıdır.
Using where
Bu ifade, MySQL'in WHERE koşulunu kullanarak eşleşen satırları filtrelediğini gösterir. Bu ifade tek başına bir sorun değildir; aslında çoğu sorguda beklenen bir durumdur. Ancak, type: ALL ile birlikte Using where görüyorsanız, bu, tablonun tamamının taranıp sonra filtrelendiği anlamına gelir ki bu da kötü bir performanstır.
Using index, Using index condition
Using index: MySQL'in sorguyu sadece indeks ağacındaki bilgileri kullanarak tamamlayabildiğini gösterir. Bu, "covering index" olarak bilinir ve veri dosyasına erişmeye gerek kalmadığı için çok verimlidir. İdeal bir durumdur.Using index condition: MySQL'in indeksi kullanarak birWHEREkoşulunu filtrelediğini gösterir. Bu, MySQL 5.6 ve sonraki sürümlerde tanıtılan bir optimizasyondur veUsing where'den daha iyidir çünkü filtreleme indeks düzeyinde yapılır.
Using join buffer
MySQL'in JOIN işlemleri için bir arabellek kullandığını gösterir. Bu, JOIN'lerin indekslenmemiş sütunlar üzerinde yapıldığında veya çok sayıda satır birleştirildiğinde görülebilir. Performans sorunlarına yol açabilir ve JOIN koşulları için indeks eklenerek genellikle önlenebilir.
WordPress Sorgularında EXPLAIN Kullanımı
WordPress'in dinamik yapısı, birçok farklı sorgu türünü beraberinde getirir. İşte bazı yaygın WordPress senaryolarında EXPLAIN'i nasıl uygulayabileceğiniz:
wp_posts ve wp_postmeta Sorguları
WordPress'in kalbi olan wp_posts tablosu, tüm yazıları, sayfaları ve özel yazı tiplerini içerir. wp_postmeta ise bu yazılarla ilgili özel alanları saklar.
-- Belirli bir yazı tipindeki yayınlanmış yazıları getiren bir sorgu
EXPLAIN SELECT ID, post_title, post_date FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 0, 10;
-- Bir meta anahtarına göre filtreleme yapan bir sorgu
EXPLAIN SELECT p.ID, p.post_title FROM wp_posts p
INNER JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND pm.meta_key = '_price' AND pm.meta_value > '100'
ORDER BY p.post_date DESC LIMIT 0, 10;
Bu sorgularda type sütununu ve Extra sütunundaki Using filesort gibi ifadeleri kontrol edin. Özellikle wp_postmeta tablosu üzerinde meta_key ve meta_value sütunları için indeksler genellikle gereklidir.
wp_options ve Otomatik Yükleme
wp_options tablosu, sitenizin ayarlarını saklar. Özellikle autoload = 'yes' olan seçenekler, her sayfa yüklemesinde çağrılır. Çok fazla otomatik yüklenen seçenek, performansı düşürebilir.
EXPLAIN SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';
Bu sorgu genellikle hızlıdır, ancak autoload sütununda indeks yoksa veya çok fazla satır varsa type: ALL görebilirsiniz.
Eklenti ve Tema Sorgularını İnceleme
Birçok eklenti ve tema, kendi karmaşık sorgularını çalıştırır. Yavaş bir eklentiyi veya temayı teşhis etmek için, yavaş sorgu günlüklerini (slow query log) analiz ederek veya sorgu izleme eklentileri kullanarak şüpheli sorguları belirleyebilir ve ardından EXPLAIN ile inceleyebilirsiniz.
Örnek Bir WordPress Sorgusu ve EXPLAIN Analizi
Diyelim ki bir WordPress blogunda popüler yazıları getiren bir sorgu var:
SELECT p.ID, p.post_title, pm.meta_value AS views_count
FROM wp_posts p
INNER JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE p.post_type = 'post' AND p.post_status = 'publish'
AND pm.meta_key = 'post_views_count'
ORDER BY CAST(pm.meta_value AS UNSIGNED) DESC
LIMIT 10;
Bu sorgunun EXPLAIN çıktısı muhtemelen wp_postmeta tablosu için type: ALL veya type: index gösterecek ve Extra sütununda Using filesort ve Using temporary içerecektir. Bunun nedeni:
meta_keyüzerinde indeks olsa bilemeta_value'nun string olması ve sayısal sıralama içinCASTkullanılması.post_views_countmeta anahtarı içinmeta_valueüzerinde indeks olmaması.
İyileştirme için wp_postmeta tablosuna (meta_key, meta_value) üzerinde bir indeks eklemek ve post_views_count meta değerlerini sayısal olarak saklamak (meta_value yerine ayrı bir sütunda) düşünülebilir.
Performans İyileştirme Stratejileri
EXPLAIN çıktısını analiz ettikten sonra, performans sorunlarını gidermek için çeşitli stratejiler uygulayabilirsiniz.
İndeksleme Stratejileri
- Eksik İndeksleri Ekleyin:
type: ALLveyatype: indexgördüğünüzde,WHEREveORDER BYkoşullarındaki sütunlar için indeksler eklemeyi düşünün. - Bileşik İndeksler: Birden fazla sütunu içeren
WHEREveyaORDER BYkoşulları için bileşik indeksler (örneğin,(post_type, post_status, post_date)) oluşturun. İndeksleme sırası önemlidir. - Covering Index (Kapsayıcı İndeks): Eğer
SELECTettiğiniz tüm sütunlar bir indeksin parçasıysa (Using indexgörürsünüz), MySQL veri dosyasına gitmek zorunda kalmaz. Bu, çok hızlıdır. - Gereksiz İndeksleri Kaldırın: Çok fazla indeks,
INSERT,UPDATE,DELETEişlemlerini yavaşlatabilir. Kullanılmayan indeksleri periyodik olarak kontrol edin ve kaldırın.
Sorgu Optimizasyonu Teknikleri
SELECT *Yerine Belirli Sütunları Seçin: Yalnızca ihtiyacınız olan sütunları seçmek, veri transferini azaltır ve bazen covering index kullanımına olanak tanır.- JOIN'leri İyileştirin: JOIN koşullarındaki sütunların indeksli olduğundan emin olun. İç içe geçmiş JOIN'lerden kaçının.
- Alt Sorguları İyileştirin: Bazı alt sorgular
JOIN'lere dönüştürülerek daha verimli hale getirilebilir. LIKE %value%Kullanımından Kaçının:LIKE '%value%'kullanımı indeksleri kullanamaz ve tam tablo taramasına yol açar. MümkünseLIKE 'value%'kullanın veya FULLTEXT indeksleri değerlendirin.
Önbellekleme ve Diğer Yöntemler
Veritabanı düzeyinde optimizasyonlar her zaman yeterli olmayabilir. WordPress siteniz için genel performans iyileştirmeleri de düşünmelisiniz:
- Nesne Önbellekleme: Redis veya Memcached gibi nesne önbellekleme çözümleri, sık kullanılan sorgu sonuçlarını önbelleğe alarak veritabanı yükünü azaltır.
- Sayfa Önbellekleme: Tam sayfa önbellekleme eklentileri (örneğin WP Rocket, LiteSpeed Cache) statik HTML kopyalarını sunarak veritabanı sorgularını tamamen atlayabilir.
- CDN Kullanımı: Statik varlıkları (resimler, CSS, JS) CDN üzerinden sunmak, ana sunucunuzun yükünü azaltır.
- Veritabanı Temizliği: Revizyonları, spam yorumları ve geçici verileri düzenli olarak temizlemek, veritabanı boyutunu küçültür ve sorgu performansını artırır.
WordPress Özel Optimizasyonlar
WordPress'e özgü bazı optimizasyonlar şunlardır:
wp_optionsTablosunu Optimize Etme:autoload = 'yes'olan seçenek sayısını minimumda tutun. Gereksiz eklentileri devre dışı bırakın.- Post Revizyonlarını Sınırlama:
wp-config.phpdosyasınadefine('WP_POST_REVISIONS', 3);ekleyerek revizyon sayısını sınırlayın. - Gereksiz Eklentileri ve Temaları Kaldırma: Kullanmadığınız eklentiler ve temalar veritabanına gereksiz yük bindirebilir.
Sonuç
MySQL EXPLAIN planını okumak, WordPress sitenizin veritabanı performansını derinlemesine anlamak ve optimize etmek için vazgeçilmez bir beceridir. type ve Extra sütunlarına özellikle dikkat ederek, sorgularınızdaki darboğazları kolayca tespit edebilir ve doğru indeksleme veya sorgu yeniden yazma stratejileriyle sitenizin hızını önemli ölçüde artırabilirsiniz. Unutmayın, iyi bir performans, iyi optimize edilmiş bir veritabanıyla başlar ve EXPLAIN bu yolculukta en iyi arkadaşınızdır.
SSS (Sık Sorulan Sorular)
1. EXPLAIN çıktısında ALL görmek her zaman kötü müdür?
Evet, genellikle ALL (tam tablo taraması) en kötü performans göstergesidir. Küçük tablolar için etkisi minimal olabilir, ancak orta veya büyük boyutlu tablolarda ciddi performans sorunlarına yol açar. Bu durumda indeksleme eksikliğini kontrol etmelisiniz.
2. Using filesort ve Using temporary ifadelerini nasıl ortadan kaldırabilirim?
Using filesort genellikle ORDER BY veya GROUP BY ifadelerinde uygun indeksin olmamasından kaynaklanır. Bu sütunlara indeks ekleyerek veya bileşik indeksler kullanarak ortadan kaldırabilirsiniz. Using temporary ise karmaşık GROUP BY, DISTINCT veya ORDER BY kombinasyonlarında ortaya çıkar; sorguyu basitleştirmek veya indeksleme stratejilerini gözden geçirmek yardımcı olabilir.
3. WordPress'te hangi tablolara daha çok dikkat etmeliyim?
Genellikle wp_posts, wp_postmeta, wp_options ve wp_terms tabloları en yoğun kullanılanlardır. Özellikle wp_postmeta tablosundaki meta_key ve meta_value sütunları üzerinde sıkça sorgu çalıştırıldığından, bu sütunlara uygun indeksler eklemek kritik öneme sahiptir.
4. EXPLAIN sadece SELECT sorguları için mi kullanılır?
Hayır, MySQL 5.6 ve sonraki sürümlerde EXPLAIN aynı zamanda INSERT, UPDATE ve DELETE sorguları için de kullanılabilir. Bu, veri değiştirme işlemlerinin nasıl etkilendiğini anlamanıza yardımcı olur.
5. WordPress eklentileri veya temaları tarafından oluşturulan sorguları nasıl bulabilirim?
Yavaş sorgu günlüklerini (slow query log) MySQL sunucunuzda etkinleştirebilirsiniz. Ayrıca, Query Monitor gibi WordPress eklentileri, her sayfa yüklemesinde çalışan tüm sorguları ve sürelerini göstererek sorunlu sorguları belirlemenize yardımcı olabilir.