Mysql

如何創建一個帶有索引的表,允許我從現在開始訂購?

  • July 15, 2022

我有一個帶有日期時間列的表。我有一個查詢目前寫成:

SELECT *
FROM foo
WHERE is_relevant = true
ORDER BY ABS(TIMESTAMPDIFF(SECOND, `foo`.`date`, NOW()))

目標是返回時間最接近現在的記錄——未來 1 分鐘的記錄比過去 5 分鐘的記錄更接近(按順序更低),更接近未來 1 小時的記錄,依此類推.

問題是,我認為 SQL 不能很好地管理上述查詢的索引。這是每次執行查詢時都必須計算的計算結果,我不確定如何為它創建一個高性能的記憶體值。有什麼辦法可以改善這一點嗎?

對於上下文,原始查詢要復雜得多,有多個連接;帶有時間戳的表不是從中選擇的表,而是一個連接表,用於幫助過濾和排序查詢,更糟糕的是,由於左連接,可能會出現空值。

如前所述,您的查詢將獲取“相關”行,對它們進行排序,然後返回它們。這並不比在沒有排序的情況下獲得集合差多少。

如果您將LIMIT在查詢中添加一個,那麼現在差異可能很大。如果沒有合適的索引,它仍然會執行上述步驟。另一方面,如果有合適的索引,它可能只讀取LIMIT.

繼續 ,LIMIT可以在沒有任何特殊索引的情況下進行加速:

( SELECT *
   FROM foo
   WHERE is_relevant = true
     AND date >= NOW()
   ORDER BY foo.date ASC
   LIMIT 10
) UNION ALL (
( SELECT *
   FROM foo
   WHERE is_relevant = true
     AND date < NOW()
   ORDER BY foo.date DESC
   LIMIT 10
)
ORDER BY ABS(TIMESTAMPDIFF(SECOND, `foo`.`date`, NOW()))
LIMIT 10;        -- yes, repeated

給定 `INDEX(is_relevant, date),該查詢將不會讀取超過 20 行以獲得“最接近”的 10 行。

你說真正的查詢要復雜得多。好吧,它仍然可能從找到最近的 10 個“開始”,然後JOINing到其他表。

引用自:https://dba.stackexchange.com/questions/314435