2014-02-28 141 views
8

我想弄清楚爲什麼我的Rails應用程序中的查詢之一是表現不佳。我使用的是Postgres 9.3,而使用jRuby 1.7.10的rails 4.0.3,這可能是JDBC驅動程序的問題?Rails查詢速度慢,但在pgAdmin快

但基本上,這是一個非常簡單的查詢:

SELECT * FROM table; 

表包含851行,以便它幾乎沒有一個龐大的數據集,所以我期待一個快速查詢。當我在pgAdmin 3中執行這個查詢時,我得到了我期望的結果:所有行都在15到35ms之間的任何位置返回。好而快!

從鐵軌,但它是一個不同的故事。在軌道控制檯中運行查詢,我能夠達到的最快速度爲189ms,同時通常在200ms標記附近。這個查詢通過調用Table.all

我最初的想法很簡單,就是ActiveRecord在851對象的實例化中增加開銷,所以這顯然會減慢它的速度。爲了測試這個,我跑

ActiveRecord::Base.connection.execute("SELECT * FROM table") 

有輕微加速,但同樣,幾乎所有查詢都選修了150ms,還有很長的路要走將pgAdmin的標誌。作爲我試過的最後一次嘗試

ActiveRecord::Base.connection.exec_query_raw("SELECT * FROM table") 

但是,這並沒有改善性能。

因爲我看到pgAdmin和Rails之間的性能下降了10倍,所以我現在真的難以理解爲什麼這麼慢。在Rails中執行了原始SQL之後,我知道ActiveRecord並沒有減慢速度,所以現在我對於什麼是非常困惑。

有沒有人知道爲什麼這比應該慢得多?

UPDATE

我做了一些更多的挖掘,而這似乎是在路上的軌道正在處理日期字段。如果我手動選擇表格中的所有列,速度就會很慢,但是如果我選擇除updated_atcreated_at以外的所有列,則查詢將在大約2-4ms內運行,這非常完美!

我現在唯一的問題就是如何解決這個問題。有沒有一種方法來解決日期的軌道性能問題,或者讓軌道不能將它們解析爲日期並將它們保存爲字符串或類似的?

更新2

所以做一些更多的挖掘和@stonehz指着我從這個職位上調的錯誤,我已經升級到Jruby 1.7.12rails 4.1.0,發現有相當加快之後。這與pgAdmin的表現並不是很接近,但我認爲如果不完全刪除日期列,我不會得到更好的結果。以下是我現在得到的基準

SELECT *:      4.080000 0.330000 4.410000 ( 5.243000) 
SELECT date_fields:    1.960000 0.020000 1.980000 ( 2.032000) 
SELECT * - date_fields:   3.070000 0.070000 3.140000 ( 3.247000) 
--------------------------------------------------------- total: 9.530000sec 

            user  system  total  real 
SELECT *:      3.700000 0.060000 3.760000 ( 4.663000) 
SELECT date_fields:    1.790000 0.020000 1.810000 ( 2.021000) 
SELECT * - date_fields:   2.330000 0.060000 2.390000 ( 3.180000) 

此基準查詢851行。第一個測試是一個簡單的SELECT *聲明。第二個測試只選擇日期字段,最後的測試選擇的所有字段,除了日期字段的。每個查詢正在運行100次以獲得最終結果。

如上所示,select *聲明現在只需要大約4秒鐘就可以運行100次,因此每個查詢僅採用40ms,這更接近〜30ms的pgAdmin時間。好多了!

+0

我不是一個紅寶石軌道上的傢伙,但沒有比SELECT更進一步看*我可以說,你應該開始只命名你需要的列。 ORM通常會通過一整隻狗和小馬秀將*變成一堆名稱,而不是,這可能會增加一些ms到你的總時間。對於快速實驗,你可以做SELECT 1 my_number FROM表,看看它是如何執行的? – Kuberchaun

+0

Rails不會對查詢做任何詭計,它只是運行SELECT *而不會將其更改爲單個列選擇。儘管它在生產模式中似乎加快了一點,但不如我期望的那麼快 – PaReeOhNos

+0

如果從rails控制檯運行查詢,您仍然添加另一個圖層,該圖層添加了代碼行和代碼行以處理並返回結果集數據庫。我的意見是我認爲它在某種程度上會慢一些,慢154毫秒聽起來不合理。 Pgadmin是用C++編寫的,我希望它能更好地處理顯示的處理結果集。從psql運行相同的查詢,我敢打賭它會擊敗pgadmin或匹配更糟的情況。我的觀點是,放緩的是Ruby/Rails/Active記錄而不是Postgres。並擺脫所有您的生產查詢PLZ :)的SELECT *。 – Kuberchaun

回答

1

他們已經在你身邊發現的bug解決這個問題,打開情侶門票:

https://github.com/jruby/jruby/issues/1662

https://github.com/jruby/activerecord-jdbc-adapter/issues/540

使用JRuby 1.7.12將提高5倍左右的性能(如它們的基準暗示)

+0

更新到'Jruby 1.7.12'並將導軌更新到4.1.0明確提高了速度。我已經用更多的結果更新了這個問題,但是我認爲這是最接近我能夠在沒有完全排除日期字段的情況下得到的。 – PaReeOhNos

0

因爲我看到pgAdmin和Rails之間的性能降低了10倍,所以我現在真的難住了。在Rails中執行了原始SQL之後,我知道ActiveRecord並沒有減慢速度,所以現在我對於什麼是非常困惑。

這不是ActiveRecord,它是您的查詢。

當您在pg admin中運行此查詢時,實際上它不會在我知道的情況下運行它。 PgAdmin對你的使用做出了一些假設,即你最終會得到一個巨大的集合。爲了提高性能,使用遊標更有趣,以便讓您通過根據需要獲取行來導航巨集,而不是一次全部導入。我想知道這正是發生了什麼事情。

當你在你的應用程序中運行相同的查詢時,相反,你有責任做這種事情。或者就此而言,不要開始運行這種查詢。需要從數據庫表中選擇所有行通常表示應用程序設計中出現問題。

+0

我同意運行select *是一個壞主意,但這只是一個測試,而不是實際的生產查詢正在執行:) – PaReeOhNos

相關問題