[wp-trac] [WordPress Trac] #14572: post_author_meta_box causes fatal error on site with large userbase.
WordPress Trac
wp-trac at lists.automattic.com
Mon Sep 6 09:11:57 UTC 2010
#14572: post_author_meta_box causes fatal error on site with large userbase.
----------------------------+-----------------------------------------------
Reporter: tomdebruin | Owner: scribu
Type: defect (bug) | Status: assigned
Priority: normal | Milestone: 3.1
Component: Administration | Version: 3.0.1
Severity: normal | Keywords: needs-patch gsoc
----------------------------+-----------------------------------------------
Comment(by mdawaffe):
Replying to [comment:23 scribu]:
> Why is that a dependent subquery? I don't get it.
Because the MySQL optimizer is naive in this situation:
http://dev.mysql.com/doc/refman/5.0/en/subquery-restrictions.html
You can force the inner query to be executed first by doing something
like:
{{{
EXPLAIN
SELECT DISTINCT(minibb_users.ID) FROM minibb_users
WHERE 1=1 AND minibb_users.ID IN (
SELECT user_id FROM (
SELECT user_id FROM minibb_usermeta
WHERE CASE meta_key
WHEN 'wporg_5_capabilities' THEN meta_value IS NOT NULL
END
GROUP BY user_id HAVING COUNT(*) = 1
) AS foo
) ORDER BY user_login ASC;
}}}
|| id || select_type || table || type || possible_keys || key || key_len
|| ref || rows || Extra ||
|| 1 || PRIMARY || minibb_users || index || NULL || user_login || 60 ||
NULL || 1254992 || Using where; Using index ||
|| 2 || DEPENDENT SUBQUERY || <derived3> || ALL || NULL || NULL || NULL ||
NULL || 10 || Using where ||
|| 3 || DERIVED || minibb_usermeta || index || NULL || user_id || 8 ||
NULL || 5830942 || Using where ||
The first subquery is still "dependent", but now it's only operating on a
small number of rows the derived table returns.
A JOIN is simpler, though.
The other problem with this query is the usermeta portion (whether it's in
a subquery or in a join).
{{{
EXPLAIN
SELECT * FROM wp_usermeta
WHERE CASE meta_key
WHEN 'wp_capabilities' THEN meta_value IS NOT NULL
END
}}}
|| id || select_type || table || type || possible_keys || key || key_len
|| ref || rows || Extra ||
|| 1 || SIMPLE || wp_usermeta || ALL || NULL || NULL || NULL || NULL || 59
|| Using where ||
That can't be indexed. It has to look at each row to see if it matches
one of (in this case, the only) case statement.
in _wp_meta_sql(), there's no way for the logic to result in multiple
$clauses, so why not just go with:
{{{
EXPLAIN
SELECT * FROM wp_usermeta WHERE meta_key = 'wp_capabilities'
}}}
|| id || select_type || table || type || possible_keys || key || key_len
|| ref || rows || Extra ||
|| 1 || SIMPLE || wp_usermeta || ref || meta_key || meta_key || 768 ||
const || 2 || Using where ||
Also, I don't understand the point of the {{{GROUP BY user_id HAVING
COUNT(*) = 1}}}. When would there ever be multiple wp_capabilities meta
rows for a single user_id? Even if there are, why does it matter? That
user_id would still be a member of the blog.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/14572#comment:25>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list