[wp-trac] [WordPress Trac] #31171: Very slow db query in get_lastpostmodified() which is called by WP feeds results in large table scan and sort using filesort
WordPress Trac
noreply at wordpress.org
Thu Jan 29 01:45:28 UTC 2015
#31171: Very slow db query in get_lastpostmodified() which is called by WP feeds
results in large table scan and sort using filesort
--------------------------+-----------------------------
Reporter: archon810 | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Feeds | Version: 4.1
Severity: normal | Keywords:
Focuses: performance |
--------------------------+-----------------------------
Hey guys,
In my quest to improve performance of core Wordpress functionality (see
#31071 and #31072), I'm back with another optimization that is quite
significant for large WP installations.
As far as I can tell, the issue comes up in a function called
`_get_last_post_time()`, which is used by `get_lastpostmodified()` and in
turn all the feeds `feed-rss2.php`, etc.
The query is as follows:
{{{
SELECT post_modified_gmt FROM wp_posts WHERE post_status = 'publish' AND
post_type IN ('post', 'page', 'attachment') ORDER BY post_modified_gmt
DESC LIMIT 1
}}}
In our database with 286k rows in wp_posts, this query scans 22,471 rows
and then sorts using filesort - an especially nasty operation.
Here is the result of EXPLAIN:
{{{
+----+-------------+----------+-------+-----------------------------------------------------------------+------------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys
| key | key_len | ref | rows | Extra
|
+----+-------------+----------+-------+-----------------------------------------------------------------+------------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | wp_posts | range |
type_status_date,post_status,post_type_mime_type,post_type_date |
type_status_date | 124 | NULL | 22471 | Using where; Using filesort |
+----+-------------+----------+-------+-----------------------------------------------------------------+------------------+---------+------+-------+-----------------------------+
}}}
No index is used, as you can see.
Testing it with SQL_NO_CACHE, this query runs anywhere between 1s and 3+s.
Needless to say, feeds get hit a lot by various crawlers and this query
gets run a lot too.
The fix, which results in several orders of magnitude of speed
improvements is as follows:
{{{
CREATE INDEX `modified_gmt_status_type` ON `wp_posts`(`post_modified_gmt`,
`post_status`, `post_type`);
}}}
EXPLAIN says this afterwards:
{{{
+----+-------------+----------+-------+-----------------------------------------------------------------+--------------------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys
| key | key_len | ref | rows | Extra
|
+----+-------------+----------+-------+-----------------------------------------------------------------+--------------------------+---------+------+------+--------------------------+
| 1 | SIMPLE | wp_posts | index |
type_status_date,post_status,post_type_mime_type,post_type_date |
modified_gmt_status_type | 132 | NULL | 13 | Using where; Using
index |
+----+-------------+----------+-------+-----------------------------------------------------------------+--------------------------+---------+------+------+--------------------------+
}}}
Not only is this query faster to query the database, it even returns the
result from the index directly, thus running even faster.
Please consider testing this and adding to WP core.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/31171>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list