ORDER BY

时间:2018-01-05 13:34:50

标签: mysql wordpress query-optimization

我已经在线阅读了很多教程,并在这里阅读了stackoverflow,但我仍然无法弄清楚如何解决我现在面临的问题。

我想告诉大家我是一个mysql新手所以请原谅我的noobness。

好吧,查询是这样的,它从wordpress数据库中获取我需要的信息

SELECT 
  product.ID productId, 
  product.guid productLink,
  product.post_title productTitle,
  post.ID postId,
  post.post_title postTitle,
  post.post_content postContent,
  post.post_date postDate,
  tm.slug typeSlug, tm.name typeName,
  tm2.slug langSlug, tm2.name langName,
  tm3.slug pubSlug, tm3.name pubName,
IFNULL(wl.id,0) wishlist
FROM wp_posts product
    JOIN wp_postmeta meta ON meta.meta_key = 'p2m' AND meta.meta_value=product.ID
    JOIN wp_posts post ON post.ID = meta.post_id

JOIN wp_term_relationships tr ON tr.object_id = product.ID
JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id  = tr.term_taxonomy_id AND tt.taxonomy = 'mtype'
JOIN wp_terms tm ON tm.term_id = tt.term_id

JOIN wp_term_relationships tr2 ON tr2.object_id = product.ID
JOIN wp_term_taxonomy tt2 ON tt2.term_taxonomy_id  = tr2.term_taxonomy_id AND tt2.taxonomy = 'language'
JOIN wp_terms tm2 ON tm2.term_id = tt2.term_id

JOIN wp_term_relationships tr3 ON tr3.object_id = product.ID
JOIN wp_term_taxonomy tt3 ON tt3.term_taxonomy_id  = tr3.term_taxonomy_id AND tt3.taxonomy = 'publisher'
JOIN wp_terms tm3 ON tm3.term_id = tt3.term_id

LEFT JOIN wp_yith_wcwl wl ON wl.user_id = 1 AND wl.prod_id = product.ID AND wl.post_id = post.ID


WHERE product.post_type = 'product'

ORDER BY post.post_date DESC LIMIT 0,35

当我删除“ORDER BY post.post_date DESC”时,查询的速度降低到.03秒,这真是太神奇了。但是添加了“ORDER BY post.post_date DESC”查询的速度进入惊人的10+秒太长了..

我使用了EXPLAIN,当按日期的ORDER BY进入查询时,似乎有使用filesort。

我需要让我的查询根据post_date回复结果,所以我无法弄清楚我现在可以做些什么......

此外,我想指出在Database Description of wordpress中有一个INDEX,称为“type_status_date”,可以在我的情况下使用。但是,我完全不知道在哪里使用它以及如何使用它。如果有人可以指出我的查询逻辑中的缺陷或帮助我优化查询(或索引),请执行此操作。谢谢你的关注!

P.S:我也不知道如何创建索引:)

Initial Result of EXPLAIN with ORDER BY

3 个答案:

答案 0 :(得分:0)

type_status_date的wp_post索引,将日期字段作为索引的第三个字段,

type_status_date INDEX 
post_type
post_status
post_date
ID  

所以你有一个post类型的谓词,但是你的查询中的帖子状态不包含在任何谓词中,因此它最多可以对索引进行部分索引扫描(有时称为跳过扫描或范围扫描,具体取决于db,我的sql不会轻易打球,但速度会慢一些。

这是一个最好的案例场景,索引扫描和行查找的所有这些连接和其他字段的索引扫描和行查找的成本可能太高而无法考虑甚至触摸索引与直接扫描。

如果你发布解释计划会有所帮助,这将有助于确认优化器正在做什么。以上是更通用的数据库引擎评论。

答案 1 :(得分:0)

type_status_date是一个组合索引,因此只有在您按其所有组件订购时才使用它。它不能被MySQL用于仅通过post_date进行排序。所以最好的解决方案是通过post_date添加索引。

答案 2 :(得分:0)

    JOIN wp_postmeta meta
       ON meta.meta_key = 'p2m'       -- filters
      AND meta.meta_value=product.ID  -- shows relation

令人困惑。 JOIN...ON用于说明两个表是如何相关的。过滤器属于WHERE

    WHERE ...
      AND meta.meta_key = 'p2m'
      ...

wp_postmeta没有很好的索引。更多讨论here

添加INDEX(post_date)可能会有助于提升效果,也可能无效 - 这取决于找到35个好行的速度。

EXPLAIN,我们发现最糟糕的部分是进入meta - 类似于30K行的内容。这个_估计有30行meta_key = 'p2m'。有多少行?

不幸的是,wp_postmeta并非旨在以meta_key + meta_value高效启动。这是键值存储(例如WP中的帖子)的一般问题,特别是当'值'是LONGTEXT