2015-11-25 17 views
2

我需要訂購記錄並將「熱」(提升)的記錄放在最上面。如果它的hot_expires_at列不爲空並且將來記錄是「熱」。目前,我有這個簡單的解決方案:什麼是根據當前時間訂購條件的正確方法?

ORDER BY 
    IF(hot_expires_at IS NOT NULL AND hot_expires_at > NOW(), 
     hot_expires_at, from_unixtime(0)) DESC, 
    created_at DESC 

然而這需要一個文件排序,現在我有記錄的幾十萬已經得到了令人難以置信的慢隨着時間的推移。 (如果有幫助,只有一小部分是「熱」)。

我知道我可以運行一個額外的工作,每隔幾分鐘計算一次rank字段 - 這將足夠接近實時。但是這似乎是一個蠻力解決方案。我也可以將查詢分成兩個(「熱」和「不」),並添加結合了結果的外部邏輯,但這也是非常粗糙且容易出錯的。

我正在尋找正確的方法來做到這一點在MySQL和MySQL的設施。

+0

創建一個計算字段(即Hot),其值爲1或0(Hot或Not)。然後你可以'訂購熱DESC,CreatedAt DESC' – user5151179

回答

0

我會以一種與你目前的稍有不同的方式處理這個問題。首先,我將廢除時間戳記字段hot_expires_at對於舊記錄爲NULL的概念,但對於「熱」記錄而言不是NULL。相反,我會將名稱更改爲expires_at,我會確保記錄都有這樣的字段。關於這種設計的乾淨的事情是,它可以讓你免去爲記錄是否熱的狀態存儲狀態。相反,時間戳本身包含確定標籤所需的全部信息。

爲了報告的目的,您可以通過SELECT瞭解某個記錄是否「熱」,只需檢查它是否在將來的某個時間點過期。當您使用函數NOW()它爲每個記錄的評估每次都返回一個值

SELECT *, CASE WHEN expires_at > NOW() THEN "hot" ELSE "not" END AS is_hot 
FROM your_table 
ORDER BY expires_at DESC, created_at DESC 
+0

不應該是ORDER BY ** is_hot **,expires_at DESC,created_at DESC? – StanislavL

+0

@StanislavL標籤「hot」與帖子的年齡完全相關。因此,新的熱門帖子首先會按'expires_at'降序排列。 –

0

:所以下面類型的查詢應該做的工作。正如你所提到的,你有數十萬條記錄,因此他們的評估需要很長時間。我認爲你必須修改用於IF語句的值,例如在開始查詢或使用SYSDATE()函數之前使用由NOW()初始化的變量。

「此外,SET TIMESTAMP語句影響NOW()返回的值,但不影響SYSDATE()。這意味着二進制日誌中的時間戳設置對調用SYSDATE()沒有影響。非零值會導致NOW()的每個後續調用返回該值。將時間戳設置爲零將取消此效果,以便NOW()再次返回當前日期和時間。

相關問題