Saya memiliki file csv yang ingin saya masukkan yang terdiri dari ~ 1.500 baris dan 97 kolom. Dibutuhkan sekitar 2-3 jam untuk melakukan impor penuh dan saya ingin meningkatkan ini jika ada cara. Saat ini untuk setiap baris saya sedang melakukan $ post_id = wp_insert_post dan kemudian add_post_meta untuk 97 kolom terkait dengan setiap baris. Ini sangat tidak efisien ...
Apakah ada cara yang lebih baik untuk melakukan ini dengan cara yang bisa mendapatkan post_id menjaga hubungan antara post dan nilai post_meta?
Saat ini saya sedang mencoba ini pada mesin lokal saya dengan wamp tetapi akan menjalankannya pada VPS
wp-insert-post
Corey Rowell
sumber
sumber
Jawaban:
Saya punya masalah serupa beberapa waktu yang lalu dengan impor CSV kustom, tapi saya akhirnya menggunakan beberapa SQL kustom untuk memasukkan massal. Tetapi saya belum melihat jawaban ini pada saat itu:
Optimalkan penyisipan pos dan hapus untuk operasi massal?
untuk digunakan
wp_defer_term_counting()
untuk mengaktifkan atau menonaktifkan penghitungan jangka.Juga jika Anda memeriksa sumber untuk plugin importir WordPress, Anda akan melihat fungsi-fungsi ini tepat sebelum impor massal:
dan kemudian setelah memasukkan massal:
Jadi ini mungkin sesuatu untuk dicoba ;-)
Mengimpor posting sebagai konsep alih - alih mempublikasikan , juga akan mempercepat, karena proses lambat menemukan siput unik untuk masing-masing dilewati. Misalnya, orang dapat mempublikasikannya dalam langkah-langkah yang lebih kecil, tetapi perhatikan bahwa pendekatan semacam ini perlu menandai pos yang diimpor, jadi kami tidak hanya menerbitkan konsep apa pun nanti! Ini membutuhkan perencanaan yang cermat dan kemungkinan besar beberapa pengkodean khusus.
Jika ada misalnya banyak judul posting yang serupa (sama
post_name
) yang akan diimpor, makawp_unique_post_slug()
bisa menjadi lambat, karena iterasi loop permintaan untuk menemukan siput yang tersedia. Ini mungkin dapat menghasilkan sejumlah besar permintaan db.Sejak WordPress 5.1,
pre_wp_unique_post_slug
filter tersedia untuk menghindari iterasi loop untuk siput. Lihat tiket inti # 21112 . Ini sebuah contoh:Jika seseorang mencoba misalnya
$override_slug = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"
dengan$suffix
sebagai$post_id
, maka kami akan mencatat bahwa$post_id
selalu0
untuk posting baru, seperti yang diharapkan. Ada berbagai cara untuk menghasilkan angka unik di PHP, sepertiuniqid( '', true )
. Tetapi gunakan filter ini dengan hati-hati untuk memastikan Anda memiliki siput unik. Kita bisa mis. Menjalankan kueri penghitungan grup sesudahnyapost_name
untuk memastikan.Opsi lain adalah menggunakan WP-CLI untuk menghindari batas waktu. Lihat misalnya jawaban saya diposting untuk Membuat 20.000 Posting atau Halaman menggunakan file .csv?
Kemudian kita dapat menjalankan skrip impor PHP khusus kami
import.php
dengan perintah WP-CLI:Juga hindari mengimpor sejumlah besar jenis posting hierarkis, karena UI wp-admin saat ini tidak menanganinya dengan baik. Lihat misalnya Jenis posting kustom - daftar posting - layar putih kematian
Inilah tip hebat dari @otto:
Sebelum memasukkan massal , nonaktifkan
autocommit
mode secara eksplisit:Setelah sisipan massal, jalankan:
Saya juga berpikir itu akan menjadi ide yang baik untuk melakukan pembenahan seperti:
Saya belum menguji ini pada MyISAM tetapi ini harus bekerja pada InnoDB .
Seperti disebutkan oleh @kovshenin tip ini tidak akan berfungsi untuk MyISAM .
sumber
SET autocommit=0;
sebelum sisipan, diikuti olehCOMMIT;
sesudahnya.$wpdb->query('SET autocommit = 0;');
sebelum memasukkan tetapi bisakah kita lewati$wpdb->query('START TRANSACTION;');
dalam kasus itu? Saya akan memeriksa manual MySQL untuk mempelajari lebih lanjut ;-) cheers.wp_suspend_cache_addition( true )
seharusnya BUKAN memasukkan barang-barang ke dalam cache objek. @Birgire juga mengatakan mereka tidak menguji ini dengan MyISAM - jangan repot, mesin penyimpanan tidak mendukung transaksi sehingga pengaturan autocommit atau memulai transaksi akan memiliki efek nol.Anda perlu memasukkan posting untuk mendapatkan ID Anda tetapi
$wpdb->postmeta
tabelnya terstruktur sangat sederhana. Anda mungkin dapat menggunakanINSERT INTO
pernyataan langsung , seperti ini dari dokumen MySQL:INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Dalam kasus Anda ...
Itu tidak akan berurusan dengan penyandian, serialisasi, melarikan diri, memeriksa kesalahan, duplikasi, atau apa pun, tapi saya berharap itu akan lebih cepat (meskipun saya belum mencoba).
Saya tidak akan melakukan ini di lokasi produksi tanpa pengujian menyeluruh, dan jika saya hanya perlu melakukannya sekali atau dua kali, saya akan menggunakan fungsi inti dan makan siang yang panjang sementara barang-barang diimpor.
sumber
->prepare()
pernyataan SQL Anda. Dalam skenario Anda, apa yang akan terjadi jika kolom ID di CSV berisi sesuatu seperti1, 'foo', 'bar'); DROP TABLE wp_users; --
? Sesuatu yang buruk mungkin.Saya harus menambahkan ini:
Ingatlah bahwa ini akan dilewati
do_all_pings
, yang memproses pingback, enklosur, trackback, dan ping lainnya (tautan: https://developer.wordpress.org/reference/functions/do_all_pings/ ). Pemahaman saya dari melihat kode adalah pingbacks / trackbacks / lampiran yang tertunda masih akan diproses setelah Anda menghapusremove_action
baris ini , tapi saya tidak sepenuhnya yakin.Pembaruan: Saya juga menambahkan
Di luar itu saya menggunakan:
sumber
Catatan penting tentang
'SET autocommit = 0;'
setelah pengaturan
autocommit = 0
jika skrip menghentikan eksekusi (karena beberapa alasan, sepertiexit
, kesalahan fatal atau dll ...), maka perubahan Anda TIDAK AKAN DIKELIMPAMKAN DALAM DB!Dalam hal ini
update_option
tidak akan disimpan dalam DB!Jadi, saran terbaik adalah
COMMIT
mendaftarkanshutdown
fungsi sebagai prasyarat (jika terjadi keluar yang tidak terduga).sumber