Mysql

為什麼使用 SQL_NO_CACHE 的查詢在第一次執行時執行速度較慢?

  • March 6, 2018

查詢盡可能快,僅SQL_NO_CACHE 1在 select 和 中使用limit 1。結果很好奇。第一次執行需要 0.125 - 0.203 秒。並且所有下一次執行通常需要不到 0.040 秒。是某種熱身,還是與建構查詢過程有關?

現在這不是問題,但我想知道為什麼會這樣,並儘可能避免它。

引擎 - InnoDB

MySQL 版本 - 在 5.6 和 5.7 上測試

正如另一個突出顯示的答案,查詢記憶體不是唯一的記憶體。在大多數情況下甚至不建議使用它——事實上,它在 MySQL 8.0 中已被刪除。原因是它存在可伸縮性問題(它由全域鎖管理)並且它過於頻繁地使數據無效,以至於無法在正常工作負載中使用。

但是 InnoDB 緩衝池包含經常訪問的索引和數據。第一次查詢後,一些索引和數據被記憶體,所以下次它們將從記憶體中讀取。可能某些數據/索引頁面每次查詢只訪問一次,在這種情況下,您應該能夠看到第二次和第三次執行之間的細微差別(第一次這些頁面沒有被記憶體)。

如何避免查詢執行時間的差異?好吧,沒有辦法讓查詢在第一次執行時變得更快,因為它需要從磁碟讀取。但是,如果您的緩衝池足夠大,您的查詢將總是很快。請記住,大緩衝池對 MySQL 性能非常重要。一般建議將其保留為總記憶體的 75-80%。但實際上,事情要復雜得多:

  • 其他高速記憶體和緩衝區需要空間。特別是,如果您有很多使用者,或者如果您的使用者執行許多 JOIN 或 ORDER BY,則應考慮每個會話緩衝區。
  • 緩衝池比數據庫大是沒有用的。擁有比熱數據(您經常訪問的數據)更大的數據通常是一種浪費。

另一件事是,有時每個伺服器都會重新啟動。發生這種情況時,如果只是清空緩衝池,則重新啟動後查詢會變慢-直到再次記憶體熱數據。但是你可以通過設置來避免這種情況:

innodb_buffer_pool_dump_at_shutdown = 1
innodb_buffer_pool_load_at_startup = 1

這樣,您的緩衝池將(部分)在關機時寫入磁碟並在啟動時重新載入,因此即使重新啟動後您的查詢也應該很快。

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