效率低下的SQL

时间:2011-05-04 12:49:46

标签: mysql sql wordpress wpdb

我不是MySQL专家,但我已经管理到现在一起破解可行的东西。不幸的是,我最近提出的尝试导致服务器死亡,所以显然我正在做一些非常低效的事情。任何人都可以给我一个关于问题所在的提示以及如何在不使每个网站每次都关闭的情况下获得相同结果的提示吗?

$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名。

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

提前致谢。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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是唯一的,那么您不需要group by,因为内部联接每个wp_postmeta.post_id只会提供一行。
  3. 添加了一个额外的过滤器来过滤掉视图数量较少的帖子,这限制了MySQL必须排序的行数。
  4. 消除group by 只有当wp_postmeta.post_id是唯一的时才这是正确的!