2011-05-04 63 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