2009-11-23 240 views
12

我一直在努力解決只有當數據庫空閒了一段時間才能查詢數據的問題。第一個查詢將非常緩慢,大約30秒,然後相關的查詢將快速如0.1秒。我認爲這與緩存有關,但我一直無法找到它的原因。mysql第一次查詢速度慢,然後快速查詢相關查詢

將mysql變量tmp_table_size,max_heap_table_size更改爲更大的大小除了在內存中創建臨時表之外沒有任何效果。

我不認爲這與查詢本身有關,因爲索引很好,並且在第一個慢查詢之後,同一查詢的變體不會顯示在慢查詢日誌中。我最有興趣試圖確定此問題的原因或重置有問題的緩存的方法,以便我可以解決問題。

+3

我不是MySQL的專家,但你也許應該補充的MySQL版本中, OS信息和引擎信息(MyISAM,InnoDB?) – 2009-11-23 23:51:56

+0

好的建議,5.0.26-standard-log和InnoDB。
Linux 2.4.21-47.ELsmp#1 SMP Wed Jul 5 20:30:30 EDT 2006 x86_64 x86_64 x86_64 GNU/Linu – 2009-11-24 00:07:39

+0

這屬於http://www.serverfault.com – 2009-11-24 21:47:34

回答

7

innodb數據文件的頁面緩存在innodb緩衝池中。這是你所期望的。即使在好的硬盤驅動器上讀取文件也很慢,尤其是隨機讀取,這主要是數據庫看到的。

這可能是您的第一個查詢正在進行某種表掃描,將大量頁面拉入緩衝池,然後訪問它們的速度很快。或類似的東西。

這是我所期望的。

理想情況下,對所有表使用相同的引擎(例外:系統表,臨時表(可能)和非常小的表或短期的表)。如果你不這樣做,那麼他們必須爭取公羊。

假設您的所有表都是innodb,請使緩衝池使用高達服務器物理內存的75%(假設您不在計算機上運行太多其他任務)。

然後,你將能夠將12G左右的數據庫轉換爲內存,所以一旦「熱身」,數據庫的「最常用」12G將會出現在內存中,訪問數據庫的速度非常快。

的MySQL的一些用戶傾向於「熱身」生產服務器之後通過發送他們從其他機器複製查詢了一段時間重新啓動(這將是複製的奴隸),直到他們增加他們進入他們的生產池。這可以避免緩存很冷時出現的極端緩慢。例如,YouTube做到這一點(或至少它曾經,谷歌收購了他們,他們現在可以使用谷歌-FU)

+0

答案竟然是改變mysql配置文件並調整innodb。隨着innodb變量的大小增加,數據庫現在會在幾次查詢後進行熱身。我猜想發生了什麼是緩存太小,無法在內存中使用所有表索引,因此它不斷從磁盤交換,從而導致首次查詢緩慢。現在它已經足以讓他們都記憶猶新,所以問題沒有了。 – 2009-12-03 18:22:46

+0

我的問題是,是否有可能使第一個查詢更快?或者它是什麼,並且增加緩衝池是正確的方法? – 2017-06-18 17:44:21

3

你的mysql服務器上還有其他東西在運行嗎?我的想法是,也許在第一次查詢後,你的表仍然被緩存在內存中。一旦閒置,另一個進程將導致它被解除緩存。只是一個猜測。

你有多少內存還有其他什麼東西在運行?

+0

mysql是唯一運行的服務器。它有16Gb的內存。我同意將它從內存中取消緩存,但我無法弄清楚它在哪裏緩存,因此我可以解決問題。我不知道它是否是一個MySQL配置問題,Linux配置問題,SQL問題等。我已經搜索了其他人有同樣的問題,但沒有任何問題的洞察力。 – 2009-11-24 00:05:16

+0

基於此:http://dev.mysql.com/doc/refman/5.1/en/query-cache.html,也許嘗試使query_cache_size更大。這很奇怪,因爲無論MySQL是否告訴它,Linux都應該自動保存這些東西。你也可以嘗試通用的方法來加快你的查詢速度,比如添加一個索引並且沒有大表,但是我不知道這些會對你有幫助。 – 2009-11-24 00:11:09

+0

query_cache_size設置爲零,所以這不是問題。我想知道什麼是緩存它。 – 2009-11-24 00:14:22

0

在一段時間之後運行查詢時,以及在重新運行查詢並快速獲得結果時,在Linux命令行上輸入並比較「vmstat 1」的輸出。具體檢查「bi」列(即每秒從磁盤讀取的kb)。

您可能會發現操作系統在快速情況下緩存磁盤塊(因此爲較低的「雙」數字),但緩慢情況下(因此爲較大的「雙」數字)不會緩存磁盤塊。

您可能還會發現,無論是哪種情況,vmstat都會顯示CPU的高/低使用率。如果速度較慢,並且磁盤吞吐量也很低,則即使您已指示相關配置值設置爲零,系統仍可能會返回緩存查詢。也許檢查show engine innodb statusSHOW VARIABLES的輸出並確認。

innodb_buffer_pool_size也可能被設置爲高(應該是......),甚至在操作系統可以返回之前它們會緩存這些塊。

您可能還會發現「key_buffer」設置得很高 - 這會將索引緩存到索引中,這可能會使您的選擇非常快速。

請嘗試檢查mysql performance blog網站的大量有用的信息。

+0

這是怎麼回事。服務器正在從第一個查詢的磁盤讀取innodb表,然後在運行類似查詢時使用緩存。現在我必須弄清楚如何減小ibdata1的大小。考慮到轉移到innodb_file_per_table – 2009-12-02 18:33:06

1

我有一個SSIS包被超時。查詢非常簡單,只需一個MySQL表,但它有時會返回很多記錄,有時最初需要幾分鐘才能執行,然後如果我想再次查詢,那麼只需幾毫秒。我們被ADO連接困住了,這意味着它會在30秒後超時,所以我們試圖加載的數據庫大約有一半失敗。

打我的頭靠在我第一次嘗試進行初始查詢牆後;非常簡單,只返回幾行。由於它非常簡單,因此可以快速執行,並將表設置在緩存中以加快查詢速度。在包的下一步中,我會做更復雜的查詢,它返回保持超時的大數據集。解決的問題 - 加載所有表格。我可以定期開始這樣做,通過首先執行一個簡單的查詢,複雜的查詢執行得更快。

+0

所以你說你可以在比單獨的大查詢更少的時間內執行一個小查詢加上你的原始大查詢?你會認爲MySQL會想出來,並在嘗試大型查詢之前將所需內容移到內存中。 – mpen 2013-01-28 22:53:36

0

我有問題,當MySQL 5.6在第一次查詢後空閒時間過慢。這是一個連接問題,而不是MySQL實例問題,例如如果你運行MYSQL查詢瀏覽器,執行「select * from some_queue」,將它放置幾個小時,然後執行任何查詢,它運行緩慢,同時瀏覽器的服務器或新實例上的進程將從相同的表中選擇即刻。

添加跳躍主機緩存,跳過名稱解析爲my.ini文件解決了這個問題。

我不知道那是爲什麼。爲什麼我嘗試這樣做:沒有這些選項的MySQL 5.1正在慢慢建立來自其他網絡的連接(例如,服務器是192.168.1.100,192.168.1.101連接速度快,192.168.2.100連接速度慢),MySQL 5.6沒有這樣的問題開始如此我們最初並沒有將這些添加到my.ini中。

UPD:解決了一半的情況下,實際上。將wait_timeout設置爲最大整數固定了另一半。也許我現在可以刪除跳躍主機緩存,跳過名稱解析,它不會在的情況下,100%放慢