Teknoloji

WooCommerce ve Büyük Katalog Siteleri İçin MySQL İndeksleme ve Sorgu Optimizasyonu Rehberi

WooCommerce ve MySQL Performansını Doğru Konumlandırmak

WooCommerce ile çalışan ve on binlerce hatta yüz binlerce ürüne sahip bir e-ticaret sitesinde performans sorunu yaşandığında suç genellikle hemen sunucuya ya da WordPress çekirdeğine atılır. Oysa sahada gördüğümüz tablo çoğu zaman farklı: Sorunların önemli bir kısmı MySQL tarafında yanlış veya eksik indeksleme, kötü yazılmış sorgular ve plansız büyüyen katalog yapısından kaynaklanıyor. Aynı donanım üzerinde, doğru optimize edilmiş bir veritabanı ile saniyede iki kat daha fazla istek cevaplayabilen WooCommerce kurulumları görmek mümkün.

Bu rehberde DCHost ekibi olarak, özellikle büyük ürün kataloglarına sahip WooCommerce sitelerinde MySQL tarafında neleri doğru yapmanız gerektiğini adım adım ele alacağız. Hangi tablolar kritik, hangi kolonlara nasıl indeks açılmalı, EXPLAIN çıktısını nasıl okumalı, yavaş sorguları nasıl teşhis etmelisiniz gibi pratik konulara odaklanacağız. Amaç; teorik bilgi yığını değil, doğrudan sahada uygulayabileceğiniz, WooCommerce mağazanızın hızını ve ölçeklenebilirliğini hissedilir şekilde artıracak somut bir yol haritası sunmak.

WooCommerce ve Büyük Katalogların Veritabanı Desenini Anlamak

İndeksleme ve sorgu optimizasyonuna geçmeden önce WooCommerce’in MySQL tarafında nasıl bir veri modeli kullandığını netleştirmek gerekiyor. Özellikle büyük kataloglarda, yanlış tasarlanmış meta alanları ve plansız veritabanı büyümesi çok hızlı şekilde darboğaza dönüşebiliyor.

Temel WordPress/WooCommerce tabloları

WooCommerce, WordPress’in standart tablo yapısını kullanır ve üzerine birkaç ek tablo ekler. En çok sorgulanan tablolar özetle şunlardır:

  • wp_posts: Ürünler de dahil olmak üzere tüm içerikler burada tutulur (post_type = ‘product’, ‘product_variation’ vb.).
  • wp_postmeta: Ürün fiyatı, stok bilgisi, özel alanlar gibi meta veriler burada saklanır.
  • wp_terms, wp_term_taxonomy, wp_term_relationships: Kategoriler, etiketler ve ürün özellikleri (attributes) için kullanılan taksonomi tabloları.
  • wc_order_* tabloları: Siparişler için WooCommerce’in yeni nesil özel tabloları (yeni kurulumlarda giderek daha fazla kullanılıyor).

Burada en kritik nokta, ürün katalogları büyüdükçe wp_postmeta ve taksonomi tablolarının çok hızlı şişmesidir. Bir ürün başına 30–40 meta kaydı olduğunu varsayarsak, 100.000 ürün için 3–4 milyon satırlık bir postmeta tablosu görmek hiç şaşırtıcı değildir.

WooCommerce sorgu tipleri ve yük profili

Büyük kataloglarda MySQL’e binen yükü anlamak için hangi sorgu tiplerinin öne çıktığına bakalım:

  • Listeleme ve kategori sayfaları: post_type, kategori, fiyat aralığı ve attribute filtreleriyle karmaşık JOIN ve WHERE şartları.
  • Site içi arama: Başlık, içerik ve çoğu zaman meta değerlerine göre LIKE aramaları.
  • Ürün detayı: Tek ürün için postmeta, taksonomi ve varyasyon sorguları.
  • Sepet ve ödeme adımı: Stok, fiyat ve kupon kontrolü gibi sık tekrarlanan sorgular.
  • Yönetim ve raporlama: Siparişler, satış raporları, stok raporları gibi ağır sorgular.

Bu sorguların her biri farklı indeksleme stratejileri gerektirir. Özellikle kategori + fiyat + attribute kombinasyonlu filtrelerde yanlış veya eksik indeks, CPU’yu tüketen ve saniyeler süren sorgulara yol açar.

Veritabanı tarafındaki genel ayarlar için, daha önce hazırladığımız WooCommerce için MySQL/InnoDB tuning kontrol listesi rehberine de göz atmanız faydalı olacaktır.

İndeksleme Temelleri: WooCommerce Perspektifinden

İndeks; bir tablonun belirli kolonları üzerinde oluşturulan, aramayı hızlandıran özel bir veri yapısıdır. MySQL tarafında çoğunlukla BTREE indekslerle çalışırız. WooCommerce’de indeksleri doğru kullanmak için üç temel kavramı netleştirelim:

  • Seçicilik (selectivity): Bir kolonun kaç farklı değer içerdiği. Ne kadar çok farklı değer varsa, indeks o kadar verimli olur.
  • Bileşik (composite) indeks: Birden fazla kolondan oluşan indeks. Örneğin (post_type, post_status, post_date).
  • Kaplayan (covering) indeks: Sorgunun ihtiyaç duyduğu tüm kolonların indeks içinde olması. Böylece tabloya geri dönmeye (“back to table”) gerek kalmaz.

Eşitlik ve aralık şartları için doğru sıralama

Bileşik bir indeks tasarlarken sorgunun WHERE koşullarını iyi okumak gerekir:

  • Eşitlik filtreleri (=) en başta yer almalı (ör: post_type, post_status).
  • Aralık koşulları (>, <, BETWEEN) genelde daha sonra gelir (ör: post_date, fiyat).
  • LIKE aramaları, eğer joker karakterle başlamıyorsa (value% gibi) indeksten faydalanabilir.

Örneğin, ürünleri sadece yayında olan ve product tipinde olanları tarihine göre listelemek istiyorsanız, (post_type, post_status, post_date) şeklinde bir bileşik indeks, (post_date, post_type, post_status) indeksine göre çok daha verimli olacaktır.

WooCommerce için tipik indeks ihtiyaçları

Pratikte büyük WooCommerce kataloglarında sıkça eklediğimiz bazı indeks örneklerini paylaşalım. Not: Tablonuzun öneki wp_ olmayabilir; buna göre uyarlayın.

wp_posts için indeksler

Ürün ve varyasyonların listelenmesinde en sık kullanılan alanlar post_type, post_status ve post_date’tir. Şu bileşik indeks genelde ciddi fayda sağlar:

ALTER TABLE wp_posts 
ADD INDEX idx_posts_type_status_date (post_type, post_status, post_date DESC);

Kategori sayfaları, en çok satanlar, yeni gelenler gibi listelemelerde bu indeks genellikle sorgu planını iyileştirir.

wp_postmeta için indeksler

WooCommerce’de fiyat, stok, SKU gibi kritik bilgiler postmeta tablosundadır. Çoğu sorgu şu paterni kullanır:

WHERE post_id IN (...) 
  AND meta_key = '_price' 
  AND meta_value BETWEEN 100 AND 200

Burada sadece (post_id) veya (meta_key) üzerinde indeks olması yetmez. Genelde şu iki indeksin ikisi birden işe yarar:

ALTER TABLE wp_postmeta 
ADD INDEX idx_postmeta_postid_metakey (post_id, meta_key),
ADD INDEX idx_postmeta_metakey_value (meta_key, meta_value(20));

meta_value alanı çoğu zaman TEXT türünde olduğundan, indekste prefix (örnekte 20 karakter) kullanmak gerekir. Fiyat gibi sayısal alanları mümkün olduğunca DECIMAL gibi sayısal sütunlara taşımak ve metada saklamamak da uzun vadede büyük avantaj sağlar.

Taksonomi tabloları için indeksler

Kategori ve attribute filtreleri, özellikle büyük kataloglarda ağırlaşır. WooCommerce’in yoğun kullandığı bağlantılar genelde şu şekildedir:

wp_term_relationships (object_id, term_taxonomy_id)
wp_term_taxonomy (term_taxonomy_id, taxonomy)

Genellikle şu indeksler hayat kurtarır:

ALTER TABLE wp_term_relationships 
ADD INDEX idx_tr_object_term (object_id, term_taxonomy_id);

ALTER TABLE wp_term_taxonomy 
ADD INDEX idx_tt_taxonomy (taxonomy, term_id);

EXPLAIN ile Sorgu Planını Okumayı Öğrenmek

İyi bir indeks tasarımı yapmanın tek yolu, MySQL’in sorgularınızı nasıl çalıştırdığını anlamaktır. Bunun için en temel araç EXPLAIN komutudur.

EXPLAIN nasıl kullanılır?

Herhangi bir SELECT sorgusunun başına EXPLAIN ekleyerek MySQL’in sorgu planını görebilirsiniz:

EXPLAIN SELECT * 
FROM wp_postmeta 
WHERE meta_key = '_price' 
  AND meta_value BETWEEN 100 AND 200;

Çıktıda en çok dikkat etmeniz gereken sütunlar:

  • type: ref, range, ALL gibi değerler. ALL genelde full table scan anlamına gelir ve kaçınılmalıdır.
  • key: MySQL’in kullandığı indeks. NULL ise indeks kullanmıyordur.
  • rows: MySQL’in tahmini olarak kaç satır tarayacağı. Mümkün olduğunca düşük olmalı.
  • Extra: “Using where”, “Using filesort”, “Using temporary” gibi ifadeler performans hakkında ipucu verir.

Örnek: Fiyat filtresi yavaşlığı

Gerçek bir senaryodan sadeleştirilmiş bir örnek düşünelim. Büyük bir katalogda, ziyaretçi kategori sayfasında fiyat filtresi kullandığında sorgu 2–3 saniye sürüyor olsun. EXPLAIN çıktısında şunu görüyoruz:

  • Tablo: wp_postmeta
  • type: ALL
  • key: NULL
  • rows: 3.000.000
  • Extra: Using where; Using temporary; Using filesort

Bu, MySQL’in tüm postmeta tablosunu taradığını, sonuçları geçici tabloda tuttuğunu ve ekstra sıralama yaptığını gösterir. Bir önceki bölümdeki idx_postmeta_metakey_value indeksi eklendikten sonra aynı sorgunun EXPLAIN çıktısı şöyle görünmeye başlar:

  • type: range
  • key: idx_postmeta_metakey_value
  • rows: 15.000
  • Extra: Using where

Taradığı satır sayısı 3 milyon yerine 15 bin civarına inmiş olur. Gerçek dünyada bu, 2–3 saniyelik sorgunun 100–200 ms seviyesine düşmesi anlamına gelir.

Büyük Kataloglarda Tipik Yavaş Sorgular ve Çözümleri

Sahada WooCommerce mağazalarında en sık karşımıza çıkan yavaş sorgu tiplerini ve bunlara karşı uyguladığımız çözümleri özetleyelim.

1. Kategori + fiyat + attribute filtreleri

Ziyaretçi; kategori sayfasında belirli bir fiyat aralığı ve birden fazla attribute seçtiğinde, WordPress tarafı genellikle karmaşık bir JOIN yapısı üretir. Bu sorgular:

  • wp_posts üzerinde post_type, post_status ve post_date filtreleri,
  • wp_term_relationships ve wp_term_taxonomy ile kategori/attribute filtreleri,
  • wp_postmeta üzerinden fiyat ve stok filtreleri

içerir. Sorunlar çoğu zaman şuralarda çıkar:

  • term_relationships tablosunda (object_id, term_taxonomy_id) bileşik indeks eksikliği,
  • postmeta üzerinde hem post_id hem meta_key’e göre sorgularken yetersiz indeks,
  • LIMIT + OFFSET ile derin sayfalara gitmek (ör. sayfa 50, OFFSET 2400).

Çözümler:

  • Yukarıda önerdiğimiz bileşik indeksleri eklemek.
  • Derin sayfalarda OFFSET yerine seek pagination (son ürün ID’sine göre devam eden sayfalama) tasarlamak.
  • Attribute filtreleri için mümkünse ayrı, daha sade bir indeks tablosu kurgulamak (örneğin ürün-id + facet değerleri).

2. Varyasyonlu ürünlerin şişirdiği sorgular

Her varyasyonun ayrı bir post (product_variation) olarak tutulması, büyük kataloglarda wp_posts ve wp_postmeta üzerinde ciddi yük oluşturur. Örneğin 1 ana ürün + 100 varyasyon = 101 satır ve yüzlerce meta kaydı demektir.

Çözümler:

  • Varyasyon verilerini çekerken SELECT * yerine sadece gerekli alanları seçmek.
  • Varyasyon meta verilerinde sık kullanılan alanlar için (post_id, meta_key) bileşik indeksleri kontrol etmek.
  • Ürün listeleme sorgularında varyasyonları mümkün olduğunca dışarıda bırakmak, sadece ana ürünler üzerinden filtreleme yapmak.

3. Stok ve kampanya cron görevleri

WooCommerce, stok güncelleme, kampanya başlangıç/bitiş kontrolü, sepet temizleme gibi işleri cron görevleriyle yürütür. Özellikle çok sayıda ürün için stok senkronizasyonu yapan entegrasyonlarda, arka planda çalışan sorguların indekslenmemiş olması hem cron süreçlerini yavaşlatır hem de son kullanıcı sorgularını etkiler.

Çözümler:

  • Stok ve fiyat güncelleme sorgularını inceleyip, WHERE koşullarına uygun indeksler oluşturmak.
  • Toplu UPDATE/DELETE işlemlerini küçük parçalara bölmek (örneğin LIMIT 1000 ile adım adım).
  • Yoğun cron süreçlerini trafik dışı saatlere kaydırmak ve gerektiğinde ayrı bir veritabanı replikasında çalıştırmak.

Veritabanını ayrı bir sunucuya taşımanın mantıklı olduğu eşiği tartıştığımız WooCommerce için ayrı veritabanı ve önbellek sunucusu ne zaman mantıklı yazımızı da bu noktada okumanızı öneririz.

4. Yönetim paneli raporları

WooCommerce rapor ekranları, özellikle tarih aralığı geniş olan sipariş ve satış istatistikleri istendiğinde ağır sorgular üretir. Çoğu zaman:

  • Geniş tarih aralıklarında COUNT, SUM gibi toplama fonksiyonları,
  • Sipariş tablosu ile meta tablolar arasında birden çok JOIN,
  • İndekslenmemiş tarih ve durum filtreleri

görürüz. Yönetim arayüzü, gerçek kullanıcı tarafındaki performansı doğrudan etkilemese de, aynı veritabanı sunucusunu kullandığı için anlık CPU ve IO patlamalarına neden olabilir.

Çözümler:

  • Sipariş tablolarında (status, date_created) gibi alanlar için bileşik indeksler oluşturmak.
  • Çok sık kullanılan raporlar için özet (aggregate) tablolar kurup, cron ile bu tabloları güncel tutmak.
  • Gerekirse raporları okuma replikası (read replica) üzerinde koşturmak. Bu mimariyi ele aldığımız ProxySQL ile MySQL read/write split rehberimiz bu konuda iyi bir başlangıç noktasıdır.

    Sorgu Optimizasyonu: Sadece İndeks Değil

    İndeksler çok önemlidir ama tek başına yeterli değildir. Aynı kötü yazılmış sorguya 5 farklı indeks eklemek yerine, sorguyu doğru kurgulamak çoğu zaman daha büyük kazanım sağlar.

    SELECT * yerine hedefe yönelik kolon seçimi

    WooCommerce tema ve eklentilerinde sık gördüğümüz bir hata: Her yerde SELECT * kullanmak. Özellikle postmeta gibi geniş tablolarda bu, gereksiz IO anlamına gelir. Örneğin listeleme sorgusunda sadece ID, post_title ve post_date gerekiyorsa:

    SELECT ID, post_title, post_date 
    FROM wp_posts 
    WHERE post_type = 'product' AND post_status = 'publish'
    ORDER BY post_date DESC 
    LIMIT 20;
    

    şeklinde daraltılmış bir sorgu, hem indekslerin daha verimli kullanılmasını sağlar hem de bellek kullanımını azaltır.

    LIMIT + OFFSET yerine seek pagination

    Büyük kataloglarda sayfa 1–3 genelde sorun olmaz ama 30–40. sayfalara gidildiğinde OFFSET değeri büyüdüğü için MySQL yüzlerce bin satırı taramak zorunda kalır. Bunun yerine ID veya tarih bazlı “seek pagination” kullanmak daha iyidir:

    • İlk sorguda son ürün ID’sini alın.
    • Sonraki sayfa için WHERE ID < son_id AND LIMIT 20 gibi bir koşulla devam edin.

    Böylece MySQL her seferinde sadece gerekli aralığı tarar, OFFSET yüzünden baştan itibaren saymaya zorlanmaz.

    COUNT(*) ve istatistik sorgularını hafifletmek

    Özellikle filtreli arama sayfalarında, toplam sonuç sayısını göstermek için COUNT(*) çalıştırmak yaygın bir pratiktir. Ancak karmaşık JOIN’li sorgularda bu çok ağır olabilir. Çözümler:

    • Derin sayfalama nadiren kullanılıyorsa, kesin sayı yerine “50+ ürün” gibi aralıklı gösterimler düşünmek.
    • COUNT(*) için daha hafif, sadece ID üzerinden çalışan alternatif sorgular yazmak.
    • Yoğun kullanılan sabit filtreler için önceden hesaplanmış sayaçlar tutan ayrı tablolar tasarlamak.

    Denormalizasyon ve özet tablolar

    Teorik olarak en temiz veritabanı tasarımı her zaman en hızlısı değildir. WooCommerce gibi okuma ağırlıklı (read-heavy) sistemlerde, bazı verileri özet tablolarda ikinci kez saklamak kabul edilebilir ve hatta önerilir.

    Örneğin, kategori + fiyat aralığı + attribute kombinasyonları için çok sık aynı filtreler kullanılıyorsa, bu kombinasyonların ürün ID listelerini tutan bir “facet index” tablosu tasarlamak mümkündür. Arka planda cron veya queue sistemiyle güncellenen bu tablo, ön yüzdeki sorguları dramatik biçimde hafifletebilir.

    MySQL Sunucu Ayarları ve Altyapı Etkisi

    İndeks ve sorgu optimizasyonu ne kadar iyi olursa olsun, veritabanı sunucusunun temel ayarları ve altyapısı sağlıklı değilse beklenen kazanımı tam olarak göremezsiniz. Özellikle:

    • innodb_buffer_pool_size boyutu (aktif veri setinizin mümkün olduğunca büyük kısmını RAM’de tutacak şekilde).
    • innodb_log_file_size ve innodb_flush_log_at_trx_commit gibi yazma performansını etkileyen parametreler.
    • Disk performansı (NVMe SSD ile IOPS ve gecikme avantajı).

    Bu ayarların detaylarını ve WooCommerce yükleri için nasıl hesaplanacağını, başta bahsettiğimiz MySQL/InnoDB tuning rehberimizde kapsamlı şekilde anlattık.

    Ayrıca kapasite planlaması yaparken yalnızca veritabanını değil, PHP-FPM, Redis ve web sunucusunu da birlikte düşünmeniz gerekir. Toplam kaynak ihtiyacını hesaplamak için WooCommerce kapasite planlama rehberimizden faydalanabilirsiniz.

    İzleme, Slow Query Log ve Güvenli Değişiklik Süreci

    Başarılı indeksleme ve sorgu optimizasyonu tek seferlik bir iş değil, sürekli bir süreçtir. Bunu yönetilebilir kılmak için birkaç temel pratiği oturtmanızı öneriyoruz.

    Slow query log kullanımı

    MySQL’in slow_query_log özelliği, belirli bir eşik süreden uzun süren sorguları kaydeder. Büyük WooCommerce sitelerinde:

    • long_query_time değerini örneğin 0.5–1 saniye aralığında başlatabilirsiniz.
    • Logları düzenli aralıklarla analiz edip, en sık ve en ağır sorguları tespit edin.
    • Her iyileştirmeden sonra aynı sorguların tekrar loga düşüp düşmediğini takip edin.

    Log analizi için çeşitli araçlar kullanılabilir; ancak basit grep/sort işlemleri bile ilk etapta oldukça işe yarar.

    Test ortamı ve şema değişiklikleri

    Canlı bir WooCommerce veritabanına doğrudan ALTER TABLE komutları çalıştırmak risklidir; özellikle milyonlarca satırlık tablolarda kilitlenme ve kesinti yaşanabilir. Bu yüzden:

    • Önce staging/test ortamında aynı tablo yapısı ve benzer veri hacmiyle değişiklikleri deneyin.
    • İndeks ekleme gibi işlemler için mümkün olduğunca çevrim içi (online) çalışan araçları değerlendirin.
    • Her kritik değişiklik öncesi mutlaka güncel ve test edilmiş bir yedeğiniz olsun.

    Yedek tarafında nereden başlamanız gerektiğini, MySQL/MariaDB yedekleme stratejileri rehberimizde detaylı olarak anlattık. Şema değişikliklerini sıfır kesintiyle yapmak istediğiniz senaryolar içinse MySQL’de sıfır kesinti şema değişiklikleri yazımız yol gösterici olacaktır.

    DCHost Altyapısında WooCommerce ve MySQL İçin Yol Haritası

    DCHost tarafında, özellikle büyük kataloglu WooCommerce siteleri için işi yalnızca “bir veritabanı sunucusu verelim” seviyesinde bırakmıyoruz. Saha deneyimlerimize göre en sağlıklı ilerleme şu adımlarla oluyor:

    • Mevcut site üzerinde kısa bir slow query analizi ve EXPLAIN incelemesi.
    • Kritik tablolar için indeks denetimi ve öneri listesi.
    • MySQL/InnoDB ayarlarının, site trafiği ve veri hacmine göre yeniden boyutlandırılması.
    • Gerekiyorsa uygulama ve veritabanı sunucusunu ayırma, okuma/yazma ayrımı ve replikasyon senaryoları.

    Altyapı tarafında NVMe diskli VPS, yüksek kaynaklı dedicated sunucu veya kendi fiziki donanımınızı veri merkezimize getirebileceğiniz colocation modelleriyle, WooCommerce mağazanızın veritabanı katmanını ölçeklendirebileceğiniz esnek seçenekler sunuyoruz. Ancak hangi mimarinin sizin için anlamlı olduğuna karar vermeden önce, mutlaka sorgu ve indeks tarafını netleştirmek en maliyet-etkin yaklaşım olacaktır.

    Özet ve Uygulanabilir Yol Haritası

    WooCommerce ve büyük katalog sitelerinde MySQL performansını iyileştirmek, sihirli tek bir ayarla değil; doğru indeksler, makul sorgular ve sağlıklı bir altyapının birleşimiyle mümkün oluyor. Bu rehberde, en çok sorun yaşanan tabloları (wp_posts, wp_postmeta, taksonomi ve sipariş tabloları), bunlar için pratik indeks örneklerini ve EXPLAIN çıktısını yorumlamanın temel prensiplerini paylaştık. Özellikle kategori + fiyat + attribute filtrelerinin ve varyasyonlu ürünlerin veritabanı tarafında nasıl yük oluşturduğunu ve bunlara karşı neler yapabileceğinizi gördük.

    Buradan sonra atabileceğiniz somut adımlar şunlar olabilir:

    • Slow query log’u aktifleştirip, en ağır 10–20 sorguyu belirlemek.
    • Bu sorgular için EXPLAIN çalıştırıp, indeks ve sorgu yazımını gözden geçirmek.
    • Kritik indeksleri ekledikten sonra hem sorgu sürelerini hem de CPU/IO kullanımını tekrar ölçmek.
    • Gerekiyorsa veritabanını ayrı bir sunucuya taşıma, read replica veya ProxySQL ile read/write ayrımı gibi mimari adımları planlamak.

    Eğer WooCommerce mağazanız büyüdükçe MySQL tarafında giderek artan bir yavaşlama hissediyorsanız, DCHost ekibi olarak hem veritabanı optimizasyonu hem de uygun VPS/dedicated altyapı planlaması konusunda yanınızdayız. Mevcut sitenizin kısa bir analizini yaparak, birkaç somut indeks ve sorgu düzenlemesiyle bile ne kadar fark yaratılabileceğini birlikte görebiliriz.

Sıkça Sorulan Sorular

WooCommerce, WordPress çekirdeği üzerine kurulduğu için performans açısından en kritik tablolar genellikle wp_posts, wp_postmeta ve taksonomi tablolarıdır (wp_terms, wp_term_taxonomy, wp_term_relationships). Ürünler ve varyasyonlar wp_posts içinde tutulur; bu tabloda özellikle (post_type, post_status, post_date) gibi bileşik indeksler listeleme sorgularını ciddi hızlandırır. wp_postmeta tarafında ise (post_id, meta_key) ve meta_key + meta_value prefix indeksleri fiyat, stok, SKU gibi alanlar için hayat kurtarır. Kategori ve attribute filtrelerinde kullanılan wp_term_relationships ve wp_term_taxonomy tablolarında da object_id, term_taxonomy_id ve taxonomy alanları üzerinde doğru indeksler olmadan büyük kataloglarda verimli filtreleme yapmak oldukça zordur.

Öncelikle hangi filtre kombinasyonlarının en çok kullanıldığını belirlemek önemli. Örneğin kategori + fiyat aralığı + 1–2 attribute kombinasyonu yoğun kullanılıyorsa, sorgu tarafında bu desenleri destekleyecek bileşik indeksler tasarlamalısınız. wp_posts üzerinde post_type ve post_status eşitlik koşulları için önde, tarih veya ID gibi sıralama alanlarını sonda tuttuğunuz indeksler işe yarar. wp_postmeta tarafında ise meta_key sabit, meta_value aralıklı sorgular için (meta_key, meta_value prefix) indeksleri performansı artırır. Taksonomi tarafında (object_id, term_taxonomy_id) ve (taxonomy, term_id) indekslerini kontrol etmek gerekir. Çok karmaşık facet kombinasyonları içinse ayrı bir facet index tablosu tasarlayıp, bu tabloyu cron ile güncel tutmak uzun vadede daha sağlıklı bir çözümdür.

EXPLAIN çıktısında ilk bakmanız gereken alanlar genellikle type, key, rows ve Extra sütunlarıdır. type değeri ALL ise çoğunlukla full table scan yapıyorsunuz demektir; mümkünse bunu ref veya range seviyesine çekmek istersiniz. key sütununda NULL görüyorsanız, MySQL ilgili sorgu için hiçbir indeks kullanmıyor demektir; bu, indeks eklemeniz veya sorguyu yeniden yazmanız gerektiğinin güçlü bir sinyalidir. rows tahmini olarak kaç satır tarandığını gösterir; milyonlarla ifade ediliyorsa sorgu ağırdır. Extra alanında "Using temporary" ve "Using filesort" ifadeleri genellikle ek maliyet anlamına gelir; doğru indekslerle bunları azaltmak veya kaldırmak hedeflenmelidir.

İndeks ve sorgu optimizasyonu altyapıdan bağımsız olarak her zaman işe yarar; hatta paylaşımlı hosting ortamlarında kaynaklar kısıtlı olduğu için etkisi çoğu zaman daha belirgindir. Doğru indeksler sayesinde CPU ve IO kullanımınız düştüğü için hem kendi siteniz hızlanır hem de paylaşımlı sunucudaki limitlere daha az takılırsınız. Ancak katalog büyüklüğünüz ve trafiğiniz arttıkça, özellikle WooCommerce gibi veritabanı yoğun uygulamalarda, izole kaynaklara sahip bir VPS veya dedicated sunucuya geçmek neredeyse kaçınılmaz hale gelir. DCHost tarafında önerdiğimiz yaklaşım, önce sorgu ve indeks tarafını makul seviyeye getirmek, ardından WooCommerce kapasite planlama rehberinde anlattığımız şekilde CPU, RAM ve IOPS ihtiyacınıza uygun bir VPS/dedicated mimarisine geçişi planlamaktır.