Milyonlarca yayın için WP sitesi nasıl optimize edilir?


19

Özel bir yazı türü aracılığıyla milyonlarca gönderi oluşturacak bir şirket için bir web sitesinde çalışıyorum. Onlar dualar, bu yüzden temelde ön uçtaki kullanıcı sadece bir form aracılığıyla kısa bir cümle gönderir. Şirketin ilgilendiği tek şey gönderi içeriği ve yayınlanma tarihi. Site henüz yayınlanmadı ve zaten 120.000'den fazla gönderi var, bu yüzden milyonlarca dediğimde ciddiyim.

Yani, birkaç optimizasyon sorusu:

  1. Diyelim ki 500.000 yayını olan özel bir yazı türünde 'özellikli' kategorim var. Öne çıkan kategoride yalnızca 500 yayın var. Öne çıkan yayınlar için bir sorgu oluşturursam, 500.000 yayının tamamını mı yoksa yalnızca 500 özellikli soruyu mu sorguluyorum? Yalnızca öne çıkan on yayını görüntülemek istersem ne olur?
  2. Bu özel yazı türünü veritabanına kaydederken, özellikle gerçekten gereken tek şey yazı içeriği ve tarih olduğundan, sunucu kaynaklarını azaltmak için yapabileceğim herhangi bir şey var mı?
  3. Özel bir yazı türü kullanmalı mıyım? Prensip olarak beğendim çünkü WordPress yöneticisine iyi entegre edildi, ancak performansta önemli dezavantajlar varsa, sanırım farklı bir şey yapabilirim.

Bu ölçekte bir proje üzerinde hiç çalışmadım, bu yüzden performanstan normalden biraz daha endişeliyim. Herhangi bir yardım için teşekkürler!


WordPress işlevlerinizde ve arama komut dosyalarınızda veritabanı sorgularını minimumda tutmak önemlidir, ancak optimizasyonun büyük bir kısmı sunucunun nasıl kurulduğu ve yapılandırıldığıyla ilgilidir. Bunun için Sunucu Hatası ağında arama yapın. serverfault.com/search?q=optimize+wordpress
iyrin

@RyanLoremIpsum - yorum için teşekkürler, ama özel sorularıma cevap vermeyi umuyordum. Orada bulduğum şeylerin çoğu, WordPress'in nasıl çalıştığı ve bir kod perspektifinden nasıl optimize edileceği ile değil sunucunun kendisi ile ilgileniyor
Jeremiah Prummer

Yanıtlar:


26

1. WP_Query çalıştırılmadan önce sorguyu ayarlayın

Bu, sorguları değiştirmek için tek fırsat elbette SQL veritabanında çalıştırılmadan önce olduğundan, veritabanı sorgularını minimumda tutmaya çalışırken akılda tutulması gereken en önemli şey gibi görünüyor.

Normal Sorgular
WordPress, normal bir sorgu için, wp()sırasıyla çağrıları çağırır $wp->main( $query_vars ). Koşullu etiketlerden "is_ değişkenleri", bunları geçirmeden önce ayarlanır WP_Query->get_posts(); bu, onu MySQL veritabanı sorgusuna dönüştürür ve son olarak bunları $ wp_query nesnesinde saklar. SQL veritabanında çalıştırılmadan önce sorguyu filtrelemek mümkündür .

pre_get_postsEylem o geçmeden önce sorguyu değiştirmek için izin, bu sürecin içine takar WP_Query->get_posts().

Örneğin, "öne çıkan" kategorisindeki gönderiler için sorguyu filtrelemek istiyorsanız add_action( 'pre_get_posts', 'your_function_name' );, in_categorykoşullu etiketi kullanacak ve içine dahil edeceksiniz your_function_name.

function your_function_name( $query ) {
    if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
        // Replace 123 with the category ID of the featured category.
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'your_function_name' );

Eklenti API'sı / İşlem Başvurusu / ön gönderiler konusuna bakın «WordPress Codex

Sayfa İstekleri
"Öne çıkan" kategorisinin arşiv sayfası gibi sayfa şablonlarında olduğu gibi koşullu etiketler pre_get_postsfiltreden çalışmaz . Örneğin, is_categoryWP_Query çalışmadığından arşiv sayfasını denetlemek için kullanamazsınız .

Bunun yerine, new WP_Querygibi bir şeye benzeyen sayfa istekleri için ana sorguyu değiştirmeniz gerekir $query = new WP_Query( 'cat=123' );. Bu, sorguyu başlangıçtan itibaren uygun argümanla çalıştırır.

Bkz. Sınıf Referansı / WP Sorgusu «WordPress Codex

2. Veritabanına kaydetme

Filtreyi wp_insert_post_data, yalnızca özel gönderi türünüzle alakalı $ verilerinin döndürülmesini sağlayarak kullanabilirsiniz wp_insert_post. Özel yayın türünüzü kontrol etmek için bir koşullu ifade eklediğinizden emin olun.
Eklenti API / Filtre Referansı / wp yazılan veri ekleme «WordPress Codex

Bu kanca, özel yazı türünüzü güncellediğinizde, genellikle bir taslak kaydederek veya yayını yayınlayarak wp_update_postwp_insert_post tarafından çağrılan işlev tarafından çağrılır .

Kişisel olarak veritabanında güncellenen verilerin azaltılmasının optimizasyon önemi hakkında konuşamadığım için bunu kendiniz karşılaştırmalısınız.

3. Özel gönderi türleri performansı etkiler mi?

Deneyimlerime göre, özel gönderi türleri içeriği yönetmek için güçlü bir araçtır. Yayınları daha az kaynak kullanacak şekilde izin verdiği tüm yollarla yönetmenin başka bir yolunu bilmiyorum. Kişisel olarak mümkün olan yerlerde yapılan sorgu sayısını azaltmanın yollarını bulmaya odaklanacağım.

Kalıcı bağlantı yapısı ile ilgili bir performans sorunu vardı, bir sayı yerine metinle başladığında isabet almasına neden oldu. 3 Bu, özellikle çok sayıda sayfa barındıran siteler için zahmetliydi, ancak WordPress sürüm 3.3'ten beri çözüldü.

Burada sadece kalıcı bağlantılar getiriyorum çünkü slug genellikle permalink yapısının sürüm 3.3'ten önceki performansı etkilemiş veya etkilememiş olabilir. Bunun yanı sıra, özel gönderi türlerinin kullanımından kaynaklanan performans sorunlarının farkında değilim.

Diğer Performans Seçenekleri

Geçişler
Bu, kodunuzda sorguları minimumda tutmak için bir yedek değildir, ancak yeni sorguların gerekmemesi için sorguları bir süre saklamak için set_transient'i kullanabilirsiniz . İşte Dave Clements'in gönderisinde kullanılan örnek . Ayrıca, save_postbelirli bir gönderi türü güncellendiğinde geçici olanı silmek için bir eylem eklemeyi önerdiğini unutmayın .

<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
    $pttimestamp = time() + get_option('gmt_offset') * 60*60;
    $its_query = new WP_Query( array(
        'post_type' => 'spotlight',
        'posts_per_page' => 1,
            'post__not_in' => $do_not_duplicate,
        'meta_query' => array(
            array(
                'key' => '_hpc_spotlight_end_time',
                'value' => $pttimestamp,
                'compare' => '>'
            )
        )
    ) );
    set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
    // LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>

Daha fazla sorgu optimizasyonu
Thomas Griffin'in WordPress Sorgularını Optimize Etme eğitiminde birkaç iyi ipucu var . İşte önerilerinin kısa bir listesi:

  • 'cache_results' => falseSunucunuz Memcached gibi kalıcı önbellekleme kullanmıyorsa, tek seferlik sorgularda ayarlayın . Bir kerelik sorgular "küçük miktarlarda veri göstermek için kullanılan sorgular olarak tanımlanır. Yalnızca geçerli gönderiyle ilgili bağlantılı gönderi başlıklarını görüntülemek isteyebilir veya seçim yapmak için gönderilerin açılır listesini görüntülemek isteyebilirsiniz belirli bir seçenek ayarı. "

    Onun örneği: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • 'no_found_rows' => trueSayfalandırmanın gerekli olmadığı yeri ayarlayın . Bu "sayfalandırmaya ihtiyacımız olup olmadığını görmek için sonuçları sayarak MySQL'i atlar."

    Onun örneği: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Posta kimlikleri için yalnızca ihtiyacınız 'fields' => 'ids' olan tek şey bu olduğunda sorgulayın get_posts. Bu, Veritabanı Açıklama'ya bakarsanız her gönderi için çok fazla olan döndürülen veri miktarını önemli ölçüde azaltmalıdır. «WordPress Codex

    Onun örneği: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

Bu son ipucuna ek olarak, get_post_field kullanarak yalnızca bir veya birkaç gönderi alanına ihtiyacınız olduğunda aynı mantık uygulanabilir .

Sorgunun nasıl çalıştığına dair sağlam bir anlayışa sahip olmak çok önemlidir. Sorgularınızla ne kadar spesifik olursanız, SQL veritabanınızdan daha az çalışma talep edersiniz. Bu, veritabanı sorgularını yönetmek için çok sayıda olasılık olduğu anlamına gelir. Çalıştırdıkları yere kadar özel sorgulara dikkat edin (bir yönetici sayfası mıdır?), Doğrudan sorgularda uygun sanitizasyon kullanın ve aynı performansı elde etmenizi sağlayan yerel WordPress işlevlerini kullanmaya çalışın.


2
Mükemmel ve son derece yararlı cevap, teşekkür ederim!
Jeremiah Prummer

Tema tamamen özel olarak oluşturulmuştur, bu yüzden tam anlamıyla sadece kesinlikle gerekli öğeleri sorgularız. Bunlar da son derece yararlı. Bu göz önüne alındığında, geriye dönüp sorgularımda bazı değişiklikler yapacağım. ;)
Jeremiah Prummer

1
Mümkün olan yerlerde meta sorgulardan kaçınmanız gerektiğini ekleyeceğim. Kesinlikle aynı anda iki meta alana karşı bir sorgu çalıştırmayın. Bu, hızlı bir şekilde performans zararı haline gelen çift ve üçlü sorgularla sonuçlanır. Özel yazı türleri genellikle bu konuda yardımcı olabilir.
Charles Jaimet

3

Ayrıca ekliyorum:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (boolean) - herhangi bir sayfalandırmaya ihtiyacınız olmadığında ve bulunan toplam yayın sayısı için sayıya ihtiyaç duymadığınızda bunu doğrulayın.
  • cache_results (boolean) - Bilgi önbelleğini gönder.
  • update_post_meta_cache (boolean) - Meta bilgi önbelleği gönder.
  • update_post_term_cache (boolean) - Dönem sonu bilgi önbelleği.

Bu parametreleri kullanarak ve değerleri YANLIŞ olarak geçirerek, yürütülen bazı ekstra veritabanı sorgularını durdurarak sorguyu daha hızlı hale getirebiliriz.

Not: Bu parametreleri her zaman önbelleğe bir şeyler eklemek doğru bir şey olduğu için kullanmamalıyız, ancak bunlar belirli durumlarda yararlı olabilir ve ne yaptığınızı bildiğinizde kullanmayı düşünmelisiniz.

Lütfen ziyaret edin: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184


1
Lütfen yanıtınızı düzenleyin ve bir açıklama ekleyin: bu sorunu neden çözebilir?
fuxia


1

Tüm erken optimizasyon tipi soruları olduğu için bu soru, yalnızca siz canlı yayında çok fazla keşfedilen kesin kullanım kalıplarını bilmeden gerçekten cevaplanamaz.

Genel olarak, MYSQL spesifikasyonlarına göre veri miktarı ile ilgili herhangi bir sorun olmamalıdır. Tabii ki en iyi algoritmalarla bile veri aramak çok daha küçük tablolarla daha yavaş olacaktır, ancak bunun çözümü basit, daha güçlü CPU'dur.

Meta verilerin depolanma şeklini optimize etmek isteyebilirsiniz (örneğin, pingle ilgili verileri depolamak için değil), ancak bu tür bir şey tam olarak ne yaptığınıza bağlıdır ve sonunda daha güçlü bir CPU'ya ihtiyacınız olabilir, bu yüzden sorununuza değmeyebilir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.