Wp_insert_post এবং বর্ধিতভাবে_পোস্ট_মেটা করার দ্রুততর উপায়


16

আমার কাছে একটি সিএসভি ফাইল রয়েছে যা আমি sertোকাতে চাই যাতে ~ 1,500 সারি এবং 97 কলাম রয়েছে। সম্পূর্ণ আমদানি করতে প্রায় ২-৩ ঘন্টা সময় লাগে এবং যদি কোনও উপায় থাকে তবে আমি এটি উন্নত করতে চাই। বর্তমানে প্রতিটি সারির জন্য আমি প্রতিটি সারির সাথে associated৯ টি সম্পর্কিত কলামের জন্য একটি $ post_id = wp_insert_post এবং তারপরে একটি add_post_meta করছি। এটি বেশ অদক্ষ ...

এটির মতো আরও কীভাবে আরও ভাল উপায় যেতে পারে যে কোনও পোস্ট_আই পোস্ট এবং এর পোস্ট_মেটা মানগুলির মধ্যে সম্পর্ক রাখতে পারে?

এই মুহুর্তে আমি আমার লোকাল মেশিনে মোমবাতি দিয়ে চেষ্টা করছি তবে এটি কোনও ভিপিএসে চলবে


নীচের ডাব্লুপি টিপস ছাড়াও, এই উত্তর অনুসারে মাইএসকিউএল-এ InnoDB ব্যবহার করা এবং ব্যাচগুলিতে লেনদেনের প্রতিশ্রুতিবদ্ধ ।
ওয়েবওয়্যার

উত্তর:


21

কাস্টম সিএসভি আমদানি নিয়ে আমারও একই রকম সমস্যা হয়েছিল, তবে আমি বাল্ক সন্নিবেশের জন্য কিছু কাস্টম এসকিউএল ব্যবহার করে শেষ করেছি। তবে ততক্ষণে আমি এই উত্তরটি দেখিনি:

পোষ্ট সন্নিবেশ এবং বাল্ক অপারেশনের জন্য মুছুন?

wp_defer_term_counting()মেয়াদ গণনা সক্ষম বা অক্ষম করতে ব্যবহার করতে।

এছাড়াও আপনি যদি ওয়ার্ডপ্রেস আমদানিকারক প্লাগইনটির উত্সটি পরীক্ষা করে দেখেন তবে বাল্ক আমদানির ঠিক আগে এই ফাংশনগুলি দেখতে পাবেন:

wp_defer_term_counting( true );
wp_defer_comment_counting( true );

এবং তারপরে বাল্ক সন্নিবেশের পরে:

wp_defer_term_counting( false );
wp_defer_comment_counting( false );

তাই এটি চেষ্টা করার কিছু হতে পারে ;-)

প্রকাশের পরিবর্তে খসড়া হিসাবে পোস্টগুলি আমদানি করা বিষয়গুলিকেও গতি বাড়িয়ে তুলবে, কারণ প্রত্যেকের জন্য একটি অনন্য স্লাগ সন্ধান করার ধীর প্রক্রিয়াটি এড়ানো যায়। একটি উদাহরণস্বরূপ এগুলি ছোট পদক্ষেপে পরে প্রকাশ করতে পারে তবে নোট করুন যে এই ধরণের পদ্ধতির কোনওভাবে আমদানি করা পোস্টগুলি চিহ্নিত করা দরকার, তাই আমরা কেবল পরে কোনও খসড়া প্রকাশ করি না! এর জন্য প্রয়োজন যত্ন সহকারে পরিকল্পনা এবং সম্ভবত কিছু কাস্টম কোডিং।

যদি এখানে post_nameআমদানি করার মতো অনেকগুলি অনুরূপ পোস্ট শিরোনাম (একই ) থাকে তবে wp_unique_post_slug()একটি উপলভ্য স্লাগ সন্ধান করতে লুপ ক্যোয়ারী পুনরাবৃত্তির কারণে ধীর হয়ে যেতে পারে। এটি সম্ভবত বিপুল সংখ্যক ডিবি ক্যোরি তৈরি করতে পারে।

ওয়ার্ডপ্রেস 5.1 যেহেতু pre_wp_unique_post_slugস্লাগের জন্য লুপ পুনরাবৃত্তি এড়াতে ফিল্টার উপলব্ধ। মূল টিকিট দেখুন # 21112 । এখানে একটি উদাহরণ:

add_filter( 'pre_wp_unique_post_slug', 
    function( $override_slug, $slug, $post_id, $post_status, $post_type, $post_parent ) {
        // Set a unique slug value to shortcircuit the slug iteration loop.
        // $override_slug = ...

        return $override_slug;
    }, 10, 6
);

এক চেষ্টা যেমন যদি $override_slug = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"সঙ্গে $suffixহিসাবে $post_id, তাহলে আমরা মনে রাখবেন যে $post_idসর্বদা 0আশানুরূপ নতুন পোস্ট এর জন্য। সেখানে যদিও বিভিন্ন উপায়ে, পিএইচপি অনন্য সংখ্যার জেনারেট করতে মতো uniqid( '', true )। তবে আপনার অনন্য স্লাগ রয়েছে তা নিশ্চিত করতে এই ফিল্টারটি যত্ন সহকারে ব্যবহার করুন। আমরা উদাহরণস্বরূপ post_nameনিশ্চিত হতে পরবর্তী সময়ে একটি গোষ্ঠী গণনা ক্যোয়ারী চালাতে পারি।

আর একটি বিকল্প হ'ল সময়সীমা এড়াতে ডব্লুপি-সিএলআই ব্যবহার করা । উদাহরণস্বরূপ, .csv ফাইল ব্যবহার করে 20,000 পোস্ট বা পৃষ্ঠাগুলি তৈরি করার জন্য পোস্ট করা আমার উত্তরটি দেখুন ?

তারপরে আমরা আমাদের কাস্টম পিএইচপি আমদানি স্ক্রিপ্টটি import.phpWP-CLI কমান্ড দিয়ে চালাতে পারি :

wp eval-file import.php

বর্তমান ডাব্লুপি-অ্যাডমিন ইউআই এটি ভালভাবে পরিচালনা করে না বলে বড় আকারের শ্রেণিবিন্যাসের পোস্ট আমদানি এড়াও। যেমন কাস্টম পোস্টের ধরণ - পোস্টের তালিকা - মৃত্যুর সাদা পর্দা দেখুন

এখানে @otto থেকে দুর্দান্ত টিপস:

বাল্ক প্রবেশের আগে , autocommitমোডটি স্পষ্টভাবে অক্ষম করুন :

$wpdb->query( 'SET autocommit = 0;' );

বাল্ক সন্নিবেশের পরে, চালান:

$wpdb->query( 'COMMIT;' );

আমি আরও মনে করি যে কিছু গৃহকর্মী করা ভাল ধারণা হবে:

$wpdb->query( 'SET autocommit = 1;' );

আমি এই পরীক্ষা করা থাকেন MyISAM কিন্তু এই কাজ করা উচিত InnoDB

হিসাবে উল্লিখিত দ্বারা @kovshenin এই ডগা জন্য কাজ করবে না MyISAM


6
এটির পাশাপাশি, আপনি পূর্বে স্বতঃসংশোধন বন্ধ করতে ক্যোয়ারী ফাংশনটিও ব্যবহার করতে পারেন, এবং তারপরে সন্নিবেশ সম্পন্ন হওয়ার পরে ম্যানুয়ালি প্রতিশ্রুতিবদ্ধ। এটি বাল্ক সন্নিবেশ করার সময় ডিবি স্তরে অপারেশনগুলিকে ব্যাপকভাবে গতি দেয়। SET autocommit=0;সন্নিবেশের আগে কেবল একটি পাঠান , তারপরে একটি অনুসরণ করুন COMMIT;
অটো

মজার, এর জন্য ধন্যবাদ! আমি বাড়ি এলে তা পরীক্ষা করে দেখতে হবে।
কোরি রওয়েল

@ ওট্টো, দুর্দান্ত টিপের জন্য ধন্যবাদ। সুতরাং আমরা $wpdb->query('SET autocommit = 0;');সন্নিবেশের আগে করতে পারি কিন্তু আমরা $wpdb->query('START TRANSACTION;');কি সেই ক্ষেত্রে এড়াতে পারি ? আমি এটি সম্পর্কে আরও জানতে মাইএসকিউএল ম্যানুয়াল পরীক্ষা করব ;-) চিয়ার্স।
বিরগিরে

1
গুড পয়েন্ট মার্ক। এগুলি যদি কেবল সন্নিবেশ করানো হয় এবং আপডেট wp_suspend_cache_addition( true )না হয় তবে অবজেক্ট ক্যাশে স্টাফ রাখার ক্ষেত্রে সহায়তা করা উচিত। এছাড়াও @ বিবিরগায়ার উল্লেখ করেছেন যে তারা মাইআইএসএএম এর সাথে এটি পরীক্ষা করেননি - বিরক্ত করবেন না, স্টোরেজ ইঞ্জিন লেনদেনকে সমর্থন করে না তাই স্বতঃসংশোধ স্থাপন বা লেনদেন শুরু করা শূন্য প্রভাব ফেলবে।
কোভসেনিন

1
দুর্দান্ত টিপ আমার প্রশ্নের আগে 38 সেকেন্ড সময় নিয়েছে, এখন এটি 1 সেকেন্ড লাগে takes
অন্নপূর্ণা

5

আপনার আইডি পেতে আপনার পোস্টটি সন্নিবেশ করতে হবে তবে $wpdb->postmetaটেবিলটি কাঠামোর ক্ষেত্রে খুব সহজ। আপনি সম্ভবত মাইএসকিউএল ডক্সের মতো একটি সরল INSERT INTOবিবৃতি ব্যবহার করতে পারেন :INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

তোমার ক্ষেত্রে...

$ID = 1; // from your wp_insert_post
$values = '($ID,2,3),($ID,5,6),($ID,8,9)'; // build from your 97 columns; I'd use a loop of some kind
$wpdb->query("INSERT INTO {$wpdb->postmeta} (post_id,meta_key,meta_value) VALUES {$values}");

এটি কোনও এনকোডিং, সিরিয়ালাইজেশন, পলায়ন, ত্রুটি যাচাই, নকল বা অন্য যে কোনও কিছুর সাথে মোকাবেলা করবে না, তবে আমি এটি দ্রুত হওয়ার আশা করব (যদিও আমি চেষ্টা করেছি না)।

আমি কোনও প্রোডাকশন সাইটে এটি পুরোপুরি পরীক্ষা ছাড়াই করব না, এবং যদি আমাকে কেবল একবার বা দু'বার করতে হয় তবে আমি মূল ফাংশনগুলি ব্যবহার করব এবং জিনিসগুলি আমদানি করার সময় একটি দীর্ঘ লাঞ্চ করব।


ভাবেন আমি দীর্ঘ লাঞ্চ করে নেব, বরং আমার টেবিলগুলিতে কাঁচা ডেটা .োকাচ্ছি না এবং ওয়ার্ডপ্রেস ইতিমধ্যে কী করবে তা আবার লেখার কোনও ধারণা নেই।
কোরি রওয়েল

1
এইভাবেই মাইএসকিএল ইঞ্জেকশন হয়, সুতরাং দয়া করে এটি ব্যবহার করবেন না।
ওয়ানওফোন

@OneOfOne, সবকিছুই হার্ড-কোডড। ইনজেকশন - সংজ্ঞা দ্বারা পারে না - ব্যবহারকারীর সরবরাহ করা ইনপুট ব্যতীত ঘটতে পারে না। "ইঞ্জেকশন" এর প্রকৃতি এটি। ওপি একটি .csv ফাইল থেকে ডেটা আমদানি করছে যা তার নিয়ন্ত্রণাধীন কোড ব্যবহার করে তার নিয়ন্ত্রণাধীন। তৃতীয় পক্ষের কোনও কিছুতে ইনজেকশনের পক্ষে অপরিচ্ছন্নতা নেই। প্রসঙ্গে মনোযোগ দিন।
s_ha_dum

আমার কাছ থেকে +1, আমার 20 টি শুল্ক ক্ষেত্রের মান যুক্ত করা দরকার ছিল এবং এটি "add_post_meta" এর চেয়ে অনেক দ্রুত ছিল
জোরক্স

1
আপনি আশা করতে পারবেন না যে ওপি সিএসভি ফাইলটি আমদানি করার আগে ভালভাবে পরীক্ষা করবে এবং তাই আপনাকে এটি ব্যবহারকারীর ইনপুট এবং কমপক্ষে ->prepare()আপনার এসকিউএল স্টেটমেন্ট হিসাবে বিবেচনা করা উচিত । আপনার দৃশ্যে, যদি সিএসভিতে আইডি কলামে কিছু থাকে তবে কী হবে 1, 'foo', 'bar'); DROP TABLE wp_users; --? কিছু খারাপ সম্ভবত।
কোভসেনিন

5

আমাকে এটি যুক্ত করতে হয়েছিল:

    remove_action('do_pings', 'do_all_pings', 10, 1);

মনে রাখবেন যে এটি এড়িয়ে যাবে do_all_pings, যা পিংব্যাকস, ঘের, ট্র্যাকব্যাকস এবং অন্যান্য পিংগুলি (লিঙ্ক: https://developer.wordpress.org/references/function/do_all_pings/ ) প্রক্রিয়া করে। কোডটি দেখার থেকে আমার উপলব্ধি হ'ল আপনি এই remove_actionলাইনটি সরিয়ে দেওয়ার পরেও মুলতুবি থাকা পিংব্যাকস / ট্র্যাকব্যাকস / ঘেরগুলি প্রক্রিয়া করা হবে , তবে আমি পুরোপুরি নিশ্চিত নই।

আপডেট: আমি যোগ করেছি

    define( 'WP_IMPORTING', true );

এর বাইরে আমি ব্যবহার করছি:

    ini_set("memory_limit",-1);
    set_time_limit(0);
    ignore_user_abort(true);

    wp_defer_term_counting( true );
    wp_defer_comment_counting( true );
    $wpdb->query( 'SET autocommit = 0;' );

    /* Inserting 100,000 posts at a time
       including assigning a taxonomy term and adding meta keys
       (i.e. a `foreach` loop with each loop containing:
       `wp_insert_post`, `wp_set_object_terms`, `add_post_meta`.)
    */

    $wpdb->query( 'COMMIT;' );
    wp_defer_term_counting( false );
    wp_defer_comment_counting( false );

1

সম্পর্কে গুরুত্বপূর্ণ নোট 'SET autocommit = 0;'

সেটিংসের পরে autocommit = 0যদি স্ক্রিপ্টটি কার্যকর করা বন্ধ করে দেয় (কোনও কারণে যেমন exitমারাত্মক ত্রুটি বা ইত্যাদি ...), তবে আপনার পরিবর্তনগুলি ডিবিতে সংরক্ষণ করা যাবে না!

$wpdb->query( 'SET autocommit = 0;' );

update_option("something", "value");     

exit; //lets say, here happens error or anything...

$wpdb->query( 'COMMIT;' );

এই ক্ষেত্রে update_optionডিবি সংরক্ষিত হবে না হবে!

সুতরাং, সর্বোত্তম পরামর্শটি হ'ল পূর্বসীমা হিসাবে ফাংশনে COMMITনিবন্ধিত shutdownহওয়া (যদি কোনও অপ্রত্যাশিত প্রস্থান ঘটে তবে)।

register_shutdown_function( function(){
    $GLOBALS['wpdb']->query( 'COMMIT;' );
} );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.