If you want to test your custom SQL to see how it affects the loading time, you can try this query swapping:
/**
* Restrict the potential slow query in the meta_form() to the current post ID.
*
* @see http://wordpress.stackexchange.com/a/187712/26350
*/
add_action( 'add_meta_boxes_post', function( $post )
{
add_filter( 'query', function( $sql ) use ( $post )
{
global $wpdb;
$find = "SELECT meta_key
FROM $wpdb->postmeta
GROUP BY meta_key
HAVING meta_key NOT LIKE '\\\_%'
ORDER BY meta_key
LIMIT 30";
if( preg_replace( '/\s+/', ' ', $sql ) === preg_replace( '/\s+/', ' ', $find )
&& $post instanceof WP_Post
) {
$post_id = (int) $post->ID;
$sql = "SELECT meta_key
FROM $wpdb->postmeta
WHERE post_id = {$post_id}
GROUP BY meta_key
HAVING meta_key NOT LIKE '\\\_%'
ORDER BY meta_key
LIMIT 30";
}
return $sql;
} );
} );
Here we use the add_meta_boxes_{$post_type} hook, where $post_type = 'post'.
Here we swap the whole query, but we could also have adjusted it to support the dynamic limit.
Hopefully you can adjust this to your needs.
Update:
This potentially slow SQL core query, has now been adjusted in WP version 4.3
from
SELECT meta_key
FROM wp_postmeta
GROUP BY meta_key
HAVING meta_key NOT LIKE '\\_%'
ORDER BY meta_key
LIMIT 30
to:
SELECT DISTINCT meta_key
FROM wp_postmeta
WHERE meta_key NOT BETWEEN '_' AND '_z'
HAVING meta_key NOT LIKE '\_%'
ORDER BY meta_key
LIMIT 30;
Check out the core ticket #24498 for more info.
meta_form()function and this is indeed the generated SQL query from that core function. You could try to add your own custom metabox with modifications to the code inmeta_form()and use there your suggested SQL query. I found this #8561 closed trac ticket. You could perhaps create another ticket or try to reopen this one? PS: Notice that the parent page selecting metabox is also problematic. If you got 1 million pages, then all of them will show up as select options!meta_form()function. I updated the answer - the core SQL query has been adjusted in WP version 4.3.. Do you see any performance gain with this new SQL query compared to our additionalpost_idrestriction ?