2011-05-04 17 views
2

我不是MySQL的专家,但我已经管理到现在一起破解一些有效的东西。不幸的是,我最近的尝试导致服务器死机,所以很明显我正在做一些效率非常低的事情。任何人都可以给我一个提示,说明问题出在哪里,以及如何每次都不用整个站点都能得到相同的结果?低效SQL

$sqlbest = "SELECT 
     wp_postmeta.meta_value 
     , wp_posts.post_title 
     , wp_posts.ID 
     , (TO_DAYS(CURDATE())- TO_DAYS(wp_posts.post_date))+1 AS days 
    FROM `wp_postmeta` , `wp_posts` 
WHERE `wp_postmeta`.`post_id` = `wp_posts`.`ID` 
    AND `wp_posts`.`post_date` >= DATE_SUB(CURDATE() , INTERVAL 1 WEEK) 
    AND `wp_postmeta`.`meta_key` = 'views' 
    AND `wp_posts`.`post_status` = 'publish' 
    AND wp_posts.ID != '".$currentPostID."' 
GROUP BY `wp_postmeta`.`post_id` 
ORDER BY (CAST( `wp_postmeta`.`meta_value` AS UNSIGNED)/days) DESC 
LIMIT 0 , 4"; 

$results = $wpdb->get_results($sqlbest); 

它采用了后观看次数来计算的意见/天发表在最后,再由这个数字令他们的职位,并抓住了4强。

我想我看到它的低效它必须每次计算几千个帖子的观看次数/天,但我不知道如何做得更好。

在此先感谢。

+0

您确定这是一个效率问题,而不是简单的语法错误或代码中导致错误的其他内容?究竟发生了什么,你有什么错误吗? – 2011-05-04 12:51:46

+0

此外,您应该直接在您的服务器上运行此查询,看看会发生什么 – JohnP 2011-05-04 13:00:23

+0

尝试消除'order by'子句,看它是否有帮助 – ZaQ 2011-05-04 13:15:42

回答

0

通过静态地将它们传递到PHP服务器的查询中(可能不会与数据库同步),或者您可以编写存储过程并保存结果,从而消除每次调用这些日期函数的需要将这些日期函数转换为将在查询中使用的变量。

+0

我想我在那里了解你。但是MySQL日期函数使用那么多资源? – 2011-05-04 14:32:16

+0

当你在你的WHERE子句中使用函数时,你基本上不可能使用你的索引,所以是的,它可能会对性能产生很大的影响。 – 2011-05-04 16:44:28

0
SELECT 
    wp_postmeta.meta_value 
    , wp_posts.post_title 
    , wp_posts.ID 
    , DATEDIFF(CURDATE(),wp_posts.post_date)+1 AS days <<--1: DATEDIFF 
FROM wp_postmeta 
INNER JOIN wp_posts ON (wp_postmeta.post_id = wp_posts.ID) <<--2: explicit join 
WHERE wp_posts.post_date >= DATE_SUB(CURDATE() , INTERVAL 1 WEEK) 
    AND wp_postmeta.meta_key = 'views' 
    AND wp_posts.post_status = 'publish' 
    AND wp_posts.ID != '".$currentPostID."' 
    AND wp_postmeta.meta_value > 1 <<-- 3: extra filter 
/*GROUP BY wp_postmeta.post_id */ <<-- 4: group by not needed 
ORDER BY (CAST(wp_postmeta.meta_value AS UNSIGNED)/days) DESC 
LIMIT 0 , 4; 

我试着做一些改变。

  1. 将两个电话替换为TO_DAYS,并拨打DATEDIFF
  2. 取代了丑陋隐含的地方,加入了明确的inner join这没有做任何事情,只是使事情更清晰。它显示的一件事,如果wp_postmeta.post_id是唯一的,那么你不需要通过组,因为内部连接只会给每一wp_postmeta.post_id一行。
  3. 添加了一个额外的过滤器来过滤低查看次数的帖子,这限制了MySQL必须排序的行数。
  4. 消除group by这是唯一的,如果wp_postmeta.post_id是唯一的!
+0

谢谢约翰 - 我实际上遇到了为特定帖子的视图属性创建的两个元值的问题,所以在那里可以解决这个问题。清理数据库并按照您的建议进行操作肯定会更好。我从来不太确定内部联接,因此我会对此进行一些研究;而额外的过滤器是一个很好的主意。谢谢! – 2011-05-04 14:23:59

+0

好吧,我试过了,它返回了4个帖子。仔细检查后,似乎特定的帖子有6个meta_key“views”的条目,所有相同的数字,但是具有不同的meta_id。奇怪...... – 2011-05-04 14:38:38

+0

取而代之的是它使SELECT DISTINCT,并增加过滤器> 1000个职位。工作,但我仍然觉得我在这里做了根本性的错误... – 2011-05-04 15:17:10