Cara situs Optimalkan WP untuk jutaan posting

19

Aku sedang bekerja pada sebuah situs web untuk sebuah perusahaan yang akan sangat mungkin menciptakan jutaan posting melalui jenis posting kustom. Mereka doa, jadi pada dasarnya pengguna di ujung depan hanya menyampaikan kalimat singkat melalui formulir. Yang dipedulikan perusahaan hanyalah konten posting dan tanggal yang diposting. Situs ini bahkan tidak diluncurkan belum dan mereka sudah memiliki lebih dari 120.000 posting, jadi saya sudah mati serius ketika saya mengatakan jutaan.

Jadi, beberapa pertanyaan pengoptimalan:

  1. Katakanlah saya memiliki kategori 'fitur' di posting jenis kustom yang memiliki 500.000 posting. Kategori unggulan hanya memiliki 500 posting. Jika saya membuat query untuk tulisan fitur, saya query seluruh 500.000 posting, atau hanya 500 fitur? Bagaimana jika saya hanya ingin menampilkan sepuluh posting terbaru yang ditampilkan?
  2. Ketika menyimpan posting ini jenis kustom ke database yang ada hal-hal yang saya bisa lakukan untuk mengurangi sumber daya server, terutama karena satu-satunya hal yang benar-benar dibutuhkan adalah isi dari posting dan tanggal?
  3. Haruskah Aku bahkan menggunakan jenis posting kustom? Aku seperti itu pada prinsipnya karena itu terintegrasi dengan baik ke dalam admin WordPress, tetapi jika ada kelemahan yang signifikan dalam kinerja maka saya kira saya bisa melakukan sesuatu yang berbeda.

Saya tidak pernah bekerja pada sebuah proyek di skala ini, jadi saya sedikit lebih khawatir tentang kinerja dari biasanya. Terima kasih atas bantuan!

Yeremia Prummer
sumber
Penting untuk menjaga agar permintaan basis data tetap minimum di fungsi WordPress Anda dan memanggil skrip dengan tepat, tetapi sebagian besar optimasi berkaitan dengan bagaimana server diatur dan dikonfigurasikan. Untuk itu, cari jaringan Server Fault. serverfault.com/search?q=optimize+wordpress
iyrin
@RyanLoremIpsum - terima kasih untuk komentar, tapi aku berharap untuk jawaban untuk pertanyaan-pertanyaan khusus saya. Sebagian besar yang saya temukan di sana berkaitan dengan server itu sendiri, bukan bagaimana WordPress beroperasi dan bagaimana mengoptimalkannya dari perspektif kode
Jeremiah Prummer

Jawaban:

26

1. Setel kueri sebelum WP_Query dijalankan

Ini tampaknya menjadi hal yang paling penting untuk diingat ketika mencoba untuk menjaga permintaan database seminimal mungkin karena satu-satunya peluang untuk mengubah kueri, tentu saja, sebelum dijalankan dalam database SQL.

Kueri Normal
Untuk kueri normal, WordPress menggunakan wp()fungsi, yang pada gilirannya memanggil $wp->main( $query_vars ). "Variabel is_" dari tag kondisional ditetapkan sebelum meneruskannya WP_Query->get_posts(), yang mengubahnya menjadi permintaan basis data MySQL dan akhirnya menyimpannya dalam objek $ wp_query. Dimungkinkan untuk memfilter kueri sebelum benar-benar dijalankan dalam database SQL .

The pre_get_poststindakan kait ke proses ini, memungkinkan Anda untuk mengubah query sebelum diteruskan ke WP_Query->get_posts().

Misalnya, jika Anda ingin memfilter kueri untuk kiriman dalam kategori "unggulan", Anda akan menggunakan add_action( 'pre_get_posts', 'your_function_name' );dan menyertakan in_categorytag bersyarat di dalamnya 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' );

Lihat Plugin API / Aksi Referensi / pra mendapatkan posting «WordPress Codex

Permintaan Halaman
Adapun templat halaman, seperti halaman arsip untuk kategori "unggulan", tag kondisional tidak akan berfungsi dari pre_get_postsfilter. Misalnya, Anda tidak dapat menggunakan is_categoryuntuk memeriksa halaman arsip karena WP_Query belum berjalan.

Sebagai gantinya, Anda harus mengubah kueri utama untuk permintaan halaman dengan new WP_Queryyang akan terlihat seperti $query = new WP_Query( 'cat=123' );. Ini menjalankan kueri dengan set argumen yang sesuai dari awal.

Lihat Referensi Kelas / Pertanyaan WP «Codex WordPress

2. Menyimpan ke database

Anda dapat menggunakan filter untuk wp_insert_post_datamemastikan hanya $ data yang relevan dengan jenis kiriman khusus Anda yang dikembalikan wp_insert_post. Pastikan untuk menyertakan pernyataan bersyarat untuk memeriksa jenis pos kustom Anda.
Plugin API / Referensi Filter / masukkan data posting «WordPress Codex

Pengait ini disebut oleh wp_insert_postfungsi, yang disebut oleh wp_update_post saat Anda memperbarui jenis posting kustom Anda, biasanya dengan menyimpan konsep atau menerbitkan posting.

Anda harus membandingkannya sendiri karena saya tidak dapat berbicara secara pribadi mengenai pentingnya optimasi untuk mengurangi data yang diperbarui dalam database.

3. Apakah jenis posting kustom mempengaruhi kinerja?

Dalam pengalaman saya, jenis posting khusus adalah alat yang ampuh untuk mengelola konten. Saya tidak tahu cara lain untuk mengelola posting dengan semua cara yang memungkinkannya dengan cara yang akan menggunakan lebih sedikit sumber daya. Saya pribadi akan fokus pada menemukan cara untuk mengurangi jumlah pertanyaan yang dibuat sedapat mungkin.

Dulu ada masalah kinerja yang terkait dengan struktur permalink yang menyebabkannya terpukul ketika dimulai dengan teks, bukan angka. 3 Ini sangat menyusahkan bagi situs yang meng-hosting sejumlah besar halaman, tetapi telah dipecahkan sejak WordPress versi 3.3.

Saya hanya membawa permalink di sini karena siput biasanya merupakan bagian pertama dari struktur permalink yang mungkin atau mungkin tidak mempengaruhi kinerja sebelum versi 3.3. Selain itu, saya tidak mengetahui adanya masalah kinerja yang muncul dari penggunaan jenis posting khusus.

Opsi Kinerja Lainnya

Transien
Ini bukan pengganti untuk menjaga kueri ke minimum dalam kode Anda, tetapi Anda dapat menggunakan set_transient untuk menyimpan kueri untuk beberapa waktu sehingga kueri baru tidak diperlukan. Ini adalah contoh yang digunakan dalam posting Dave Clements . Juga, perhatikan bahwa ia merekomendasikan untuk menambahkan save_posttindakan untuk menghapus transient setiap kali jenis posting yang diberikan diperbarui.

<?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 } ?>

Lebih banyak pengoptimalan kueri
Thomas Griffin memiliki beberapa kiat bagus dalam tutorialnya Mengoptimalkan WordPress Queries . Berikut daftar singkat sarannya:

  • Diatur 'cache_results' => falsedalam pertanyaan satu kali jika server Anda tidak menggunakan caching persisten seperti Memcached. Kueri satu kali digambarkan sebagai "kueri yang digunakan untuk menunjukkan sejumlah kecil data. Bisa jadi Anda hanya ingin menampilkan judul posting terkait dengan posting saat ini, atau Anda mungkin ingin menampilkan dropdown posting untuk memilih pengaturan opsi tertentu. "

    Teladannya: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • Tetapkan di 'no_found_rows' => truemana pagination tidak diperlukan. Ini akan "memotong MySQL menghitung hasilnya untuk melihat apakah kita perlu pagination atau tidak."

    Teladannya: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Permintaan untuk ID posting hanya jika ini adalah semua yang Anda butuhkan 'fields' => 'ids' di get_posts. Ini harus secara signifikan mengurangi jumlah data yang dikembalikan, yang cukup banyak per posting jika Anda melihat Deskripsi Basis Data «WordPress Codex

    Teladannya: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

Selain tip terakhir itu, alasan yang sama dapat diterapkan ketika Anda hanya membutuhkan satu atau beberapa kolom posting dengan menggunakan get_post_field .

Memiliki pemahaman yang kuat tentang cara kerja kueri sangat penting. Semakin spesifik Anda dengan pertanyaan Anda, semakin sedikit pekerjaan yang akan Anda tuntut dari database SQL Anda. Ini berarti ada sejumlah besar kemungkinan untuk mengelola permintaan basis data. Berhati-hatilah dengan kueri khusus sejauh menjalankannya (apakah ini halaman admin?), Gunakan sanitasi yang tepat dalam kueri langsung dan coba gunakan fungsi WordPress asli yang memungkinkan Anda mencapai kinerja yang sama.

iyrin
sumber
2
Jawaban yang sangat bagus dan sangat membantu, terima kasih!
Jeremiah Prummer
Tema ini sepenuhnya dibuat khusus sehingga kami benar-benar hanya menanyakan item yang sangat penting. Ini sangat membantu. Mengingat ini, saya akan kembali dan membuat beberapa perubahan pada pertanyaan saya. ;)
Jeremiah Prummer
1
Saya ingin menambahkan bahwa Anda harus menghindari meta queri sedapat mungkin. Tentu saja tidak menjalankan kueri terhadap dua bidang meta secara bersamaan. Ini menghasilkan permintaan ganda dan tiga kali lipat yang dengan cepat menjadi nigtmare kinerja. Jenis pos khusus seringkali dapat membantu dalam hal ini.
Charles Jaimet
3

Saya juga menambahkan:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (boolean) - wujudkan ketika Anda tidak membutuhkan pagination dan tidak perlu menghitung jumlah total posting yang ditemukan.
  • cache_results (boolean) - Posting cache informasi.
  • update_post_meta_cache (boolean) - Posting cache informasi meta.
  • update_post_term_cache (boolean) - Posting cache informasi istilah

Dengan menggunakan parameter ini dan memberikan nilai-nilai sebagai FALSE, kita dapat membuat kueri lebih cepat dengan menghentikan beberapa query database tambahan yang dieksekusi.

Catatan: Kita seharusnya tidak menggunakan parameter ini selalu karena menambahkan hal-hal ke cache adalah hal yang benar untuk dilakukan, namun ini mungkin berguna dalam keadaan tertentu dan Anda harus mempertimbangkan menggunakan ketika Anda tahu apa yang Anda lakukan.

Silakan kunjungi: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184

rigosan
sumber
1
Harap edit jawaban Anda , dan tambahkan penjelasan: mengapa itu bisa menyelesaikan masalah?
fuxia
Saya tidak dapat menambahkan komentar saya pada jawaban ini: wordpress.stackexchange.com/a/166699/57674
rigosan
1

Karena semua jenis pertanyaan pengoptimalan prematur yang satu ini tidak dapat benar-benar dijawab tanpa mengetahui pola penggunaan yang tepat yang terlalu sering ditemukan hanya ketika Anda ditayangkan.

Secara umum, per spesifikasi MYSQL seharusnya tidak ada masalah dengan jumlah data. Tentu saja mencari data bahkan dengan algoritma terbaik akan lebih lambat kemudian dengan tabel yang jauh lebih kecil tetapi solusi untuk itu adalah CPU yang lebih sederhana dan kuat.

Anda mungkin ingin mengoptimalkan bagaimana meta data disimpan (misalnya untuk tidak menyimpan data terkait ping), tetapi hal seperti ini tergantung pada apa yang sebenarnya Anda lakukan, dan pada akhirnya Anda mungkin masih membutuhkan CPU yang lebih kuat sehingga mungkin tidak sepadan dengan kesulitan Anda .

Mark Kaplun
sumber