I have a table with about 10k rows. I run below sql but it's take too much time (~4 seconds):
SELECT
ID, post_date, post_title, post_name, pc.post_view,
t.name AS post_category,
pm2.meta_value AS post_image
FROM wp_posts p
INNER JOIN wp_term_relationships tr ON p.ID = tr.object_id
INNER JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy='category'
INNER JOIN wp_terms t ON tt.term_id = t.term_id AND (t.name='My Posts' OR t.name='HOT posts')
LEFT JOIN post_counter pc ON p.ID = pc.post_id
LEFT JOIN wp_postmeta pm ON pm.post_id = p.ID AND pm.meta_key = '_thumbnail_id'
LEFT JOIN wp_postmeta pm2 ON pm.meta_value = pm2.post_id AND pm2.meta_key = '_wp_attached_file'
WHERE p.post_status = 'publish' AND p.post_type = 'post'
ORDER BY FIELD(t.name, 'HOT posts', 'My Posts'), post_date DESC
LIMIT 14
If I remove "order by post_date", everything fine. It's take only 0.05 second to run.
I added some indexes with CREATE INDEX and ADD INDEX (I don't know what's difference between them):
CREATE INDEX ix_type_date ON wp_posts (post_type, post_date)
ALTER TABLE wp_posts ADD INDEX ix_status_type_date (post_status,post_type,post_date)
Then use these indexes with USE INDEX and FORCE INDEX (I also don't know what's difference between them):
...FROM wp_posts p USE INDEX (ix_type_date)...
OR
...FROM wp_posts p FORCE INDEX (ix_status_type_date)...
I still get my records, but loading time increased to 7-8 seconds.
Really need your helps! Thanks in advanced!
EDIT:
Table's structure
ID bigint(20) No
post_author bigint(20) No 0
post_date datetime No 0000-00-00 00:00:00
post_date_gmt datetime No 0000-00-00 00:00:00
post_content longtext No
post_title text No
post_excerpt text No
post_status varchar(20) No publish
comment_status varchar(20) No open
ping_status varchar(20) No open
post_password varchar(255) No
post_name varchar(200) No
to_ping text No
pinged text No
post_modified datetime No 0000-00-00 00:00:00
post_modified_gmt datetime No 0000-00-00 00:00:00
post_content_filtered longtext No
post_parent bigint(20) No 0
guid varchar(255) No
menu_order int(11) No 0
post_type varchar(20) No post
post_mime_type varchar(100) No
comment_count bigint(20) No 0
You want "Hot posts" first, then "my posts"? And there are likely to be fewer than 14 Hotties, and there are lots of "my posts"?
One clumsy solution is to
( SELECT ... name='HOT posts' ORDER BY post_date DESC LIMIT 14 )
UNION ALL
( SELECT ... name='My Posts' ORDER BY post_date DESC LIMIT 14 )
ORDER BY field(...), post_date DESC LIMIT 14
Note that there is some chance of quickly finding the latest 14 of each category, then quickly rearranging the 28 to get the desired 14.
For many-to-many tables, see here for how to improve their performance. (The default WP is rather inefficient.)
If you need to discuss further, please provide EXPLAIN SELECT ...
and SHOW CREATE TABLE
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.