I have a cron job set to remove a (sometimes large) number of posts from my database. Of course, I also need to remove all associated data such as custom fields.

This is the function I'm currently running, but it's taking a bit long to delete everything.

Would it maybe be more efficient to make a direct SQL query?

 * Delete all items
function myplugin_delete_all_items() {        
    $args = array(
            'post_type' => 'my_post_type',   
            'posts_per_page' => -1, 

    $items = new WP_Query( $args );  

    if ( $items->have_posts() ) :
        while ( $items->have_posts() ) : $items->the_post();
            $postid = get_the_ID();

            $purge = wp_delete_post( $postid, true );                


2 Answers 2


Yes, but unless you have total understanding of your system and it is going to be frozen at that state, this can be dangerous.

  1. Can you be sure that you know all the places in the DB where the post is referenced? There is the post table, the metadata table, taxonomies, and plugins. If you figure it all out, are you sure you no one will install some new plugin which uses additional tables

  2. If you use caching plugins, how will the information be deleted from the cache?

In addition, the risk, even if it is small, is probably pointless as cron processes take place away from the eye of the user so it doesn't matter much how much time they take.

  • Right, so you think there won't be much performance gains if I do a manual SQL query? You are right, it's usually done via Cron, but there is also the possibility of the user triggering it manually.
    – urok93
    Commented Mar 12, 2013 at 15:01

You can use wpdb directly to delete all posts of a certain type. wpdb::delete would be what you're looking for. Something like this...

function wpse90453_delete($post_type)
    global $wpdb;
    $wpdb->delete($wpdb->posts, array('post_type' => $post_type), array('%s'));

// usage: wpse90453_delete('my_post_type');

Keep in mind this is no where near as complete as what you're doing. wp_delete_post takes care of cleaning up everything: terms, metadata, revisions, comments, etc.

If you don't need to do any of that, then the above solution will work fine. If you do need to clean everything up, keep doing what you're doing and use wp_delete_post.

  • I need it to do all the things its currently doing for a complete cleanup, so I guess unless the code above itself can be optimized further, I'll keep it as it is.
    – urok93
    Commented Mar 12, 2013 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.