[英]Two different queries on the same table with the same WHERE clause
我有兩個不同的查詢。 但是它們都在同一個表上,並且都具有相同的WHERE
子句。 因此,他們正在選擇同一行。
查詢1:
SELECT HOUR(timestamp), COUNT(*) as hits
FROM hits_table
WHERE timestamp >= CURDATE()
GROUP BY HOUR(timestamp)
查詢2:
SELECT country, COUNT(*) as hits
FROM hits_table
WHERE timestamp >= CURDATE()
GROUP BY country
如何提高效率?
如果該表的索引正確,那么整個表有多大大小都沒關系,因為您只查看今天的行。
如果表索引不正確,無論您做什么,這些查詢的性能都會很糟糕。
您的WHERE timestamp >= CURDATE()
子句意味着您需要在timestamp
列上有一個索引。 在您的一個查詢中, GROUP BY country
顯示(timestamp, country)
的復合覆蓋索引將有很大幫助。
因此,單個復合索引(timestamp, country)
將滿足您問題中的兩個查詢。
讓我們解釋一下它是如何工作的。 為了查找今天的記錄(或者實際上是任何以特定timestamp
值開始和結束的記錄)並按國家/地區進行分組並計數,MySQL可以通過執行以下步驟來滿足查詢:
timestamp
匹配的第一條記錄的索引。 O(log n)。 country
價值。 country
值並計數。 上)。 timestamp
范圍結束。 這項索引掃描操作的速度與一組ace開發人員(MySQL團隊)以十年的辛勤工作所能達到的速度一樣快。 (您可能無法在星期六的下午超越它們。)MySQL只需一小部分索引就能滿足整個查詢,因此它背后的表有多大並不重要。
如果您在另一個查詢之后立即運行其中一個查詢,則MySQL仍有可能在RAM緩存中保留部分或全部索引數據塊,因此它可能不必從磁盤重新獲取它們。 這將提供更多幫助。
您看到示例查詢如何以timestamp
嗎? 最重要的WHERE
准則選擇時間戳范圍。 這就是為什么我建議的復合索引將timestamp
作為其第一列的原因。 如果沒有任何以country
開頭的查詢,那么該列上的簡單索引可能就沒有用了。
您詢問是否真的需要復合覆蓋指數。 您可能應該閱讀 有關它們如何工作的信息,並自己做出決定。
選擇索引時顯然需要權衡。 每個索引都會稍微減慢INSERT
和UPDATE
的過程,並且可以大大加快查詢的速度。 只有您才能解決您的特定應用程序的權衡問題。
由於兩個查詢具有不同的GROUP BY
子句,因此它們本質上是不同的,因此無法合並。 假設timestamp
字段上已經存在索引,則沒有直接的方法可以使此效率更高。
如果數據集很大(1000萬或更多行),則可以通過對country, timestamp
創建額外的組合索引而獲得一些額外的效率,但這不太可能被衡量,並且通常可以通過以下方法來緩解缺少的情況:如果這兩個查詢是在另一個查詢之后直接執行的,則為MySQL本身提供內存緩沖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.