When I insert a post I’ve found that there is a slow call to wp_unique_post_slug from within insert_post (In the database I’m using to test there is 155,000 posts – live would have considerably more). As I don’t believe a slug is important for what I’m doing (a person who is browsing our site will probably never see a single page view for this post type), is there anything I can do that can either speed up the call or (better yet) eliminate it.
Looking at the code for insert_post, I couldn’t see a way of doing it without modifying core (which is something I’d rather not do). The code I’m using is:
$post = array(
'post_title' => 'post_title',
'post_type' => 'character',
'post_status' => 'publish'
);
$post_id = wp_insert_post( $post );
Edit:
As it appears people are missing the information that I have written in this question. Here is the issue as clear as I can make it.
The Problem:
Slow performance. I have tracked this down to the function wp_unique_post_slug
called from within wp_insert_post
The code that calls wp_insert_post
:
$post = array(
'post_title' => 'post_title',
'post_type' => 'character',
'post_status' => 'publish'
);
$post_id = wp_insert_post( $post );
(yes they are all strings and not variables being assigned to $post)
Other information:
The post status needs to be ‘publish’ as these posts are presented to the user (although not in the standard WordPress manner).
I could fix it by editing core, but this is a BAD idea for a number of reasons.
A slug is not important as the user shouldn’t be going to a single page view of this content type.
I know this is really old question, but today I was dealing with something similar, and I have found a solution – if
wp_unique_post_slug()
calling is performance bottleneck, andpost_name
value is not important, then set post_name manualy to some random value.My
wp_insert_post
post action was taking too long lately (20-30s). It saves custom post typeorder
not visible to visitors, withpost_title = "Order"
(post title does not matter). That resulted in thousands of posts with title “Order”, and WP was automatically generating post names (post_name
) as “order-1”, “order-2”, “order-3”, … “order-6152” …And with every
wp_insert_post
WP searched for free post name starting from “order” and incrementing suffixed number – and every step was one DB query. So in my case WP did more than 6,000 DB queries before inserting one post to database.Setting random post_name in wp_insert_post() call disables wp_unique_post_slug() call.
Source inspection -> Abort cases
When you look at the source of
wp_unique_post_slug()
, then you’ll see that the first two lines areWhich means that there’s nothing calculated, queried or processed if
OR
inherit
and the Post Type arevision
As you can see from the source of
wp_insert_post()
wherewp_unique_post_slug()
is called, it passes the status exactly as you did.Possible solution
In case a post type isn’t public, but only visible from the admin UI, then you just have to ignore the post status, set it to draft, pending, whatever (when inserting the post) and you’re fine and nothing will be processed.
Every other attempt will fail as
$wpdb->get_var()
has no filter.MAYBE… solution
You can still use a drop in. A replacement for the
$wpdb
class/object. Just copy the contents of~/wp-includes/wp-db.php
into a new file nameddb.php
and place it into your~/wp-content
(or whatever you named it) folder.Then modify
$wpdb->get_var()
to abort in case it is called from the context ofwp_unique_post_slug()
. Then it depends on your creativity and skills if it’s faster to abort that.Keep in mind that you’ll have to update that file every time there is a core update.
Notes:
post_status
argument empty, it automatically assignsdraft
.post
post types, when no category is assigned, it automatically gets assigned the default category. But only if the post status isn’tauto-draft
.post_date_gmt
is empty and you’re adding a draft, then the value will automatically be set to'0000-00-00 00:00:00'
.post_name
(title) is empty and the status isdraft
,auto-draft
orpending
, then the title will not get sanitized.