2012-05-31 64 views
1
SELECT COUNT(*) AS count_all, products.id AS products_id 
FROM `products` 
INNER JOIN `product_device_facilities` 
    ON `product_device_facilities`.`product_id` = `products`.`id` 
INNER JOIN `product_vendors` 
    ON `product_vendors`.`ProductId` = `products`.`id` 
INNER JOIN `screen_shots` 
    ON `screen_shots`.`ProductVendorId` = `product_vendors`.`id` 
WHERE ((DownloadCount >= 10 or DownloadCount is NULL) 
    and (Minsdk <= 10 or Minsdk is null)) 
GROUP BY products.id 
HAVING GROUP_CONCAT(device_facility_id ORDER BY device_facility_id ASC) IN (0) 

這需要10秒才能完成1個拉赫(100k - > 10 Lakh = 100萬)的記錄。MySQL需要10秒才能計算出100k條記錄的條件

請幫我提高性能。

+0

什麼是表引擎? InnoDB的?發佈您的查詢「解釋」聲明。 – Vadim

+2

(請記住,不是所有我們知道山一十萬是什麼。) –

+0

10萬盧比=百萬 – manurajhada

回答

3

有幾件事你可以試試。

  1. 使用到數據庫的持久連接,以避免連接開銷
  2. 檢查所有的表都對關鍵表的主鍵例如(product_id)
  3. 通過將列聲明爲只需保留其中存儲的值的大小,就可以減少每行的RAM。即@manurajhada表示不使用count(*)使用次數(主鍵)
  4. 當您發出GRANT語句時使用更簡單的權限可以使MySQL減少權限檢查開銷。
  5. 對不同表格之間的引用使用索引。只記得不要索引太多列,簡單的經驗法則,如果你從來沒有在比較中引用列,那麼就沒有必要對它進行索引。
  6. 嘗試使用ANALYZE TABLE來幫助mysql更好地優化查詢。
  7. 您可以通過確保所有不爲空的coumns被聲明爲NOT NULL來加快查詢速度 - 因此可以加快表格遍歷的速度。
  8. 調整MySQL緩存:爲緩衝區分配足夠的內存(例如SET GLOBAL query_cache_size = 1000000)並根據平均查詢結果集大小定義query_cache_min_res_unit
  9. 我知道這聽起來反直觀,但有時候值得對錶格進行去規範化處理,即在一些表格中複製一些數據以避免昂貴的JOIN。您可以使用外鍵或觸發器支持數據完整性。

,如果一切都失敗

  1. 升級你的硬件如果可以的話,更多的內存,更快的硬盤可以使顯著差異數據庫的速度,當你已經做了分配更多的內存到MySQL。

編輯

  • 另一種選擇,如果你不需要的結果活得@問 - 比約恩·漢森建議你可以使用一個後臺任務(cron作業),每天一次,並存儲查詢結果放在一個單獨的表中,那麼在你的應用程序中,你所要做的就是檢查該表是否返回結果,這樣你就可以查詢100k結果,並且能夠運行需要花費數小時而不是過度的查詢影響你的用戶。
+0

使用count(*)將使用主鍵列,所以使用count(some_other_column)最多會以相同的速度給出相同的結果,但根據數據甚至可能會給出不同的結果。 –

+0

感謝您的詳細答覆。我已經嘗試過1-7,但沒有運氣:(。現在唯一剩下的就是調整緩存。隨着輸入參數不斷變化,我需要它們。但是使用組concat去除,減少它由2個seconds.Seems我在深陷困境。 我實際上做設備過濾的Android手機。在我的價值可能會改變。 – user1428016

1

對錶上的連接列進行索引,而不是對count(*)使用count(某些索引的主鍵列)進行索引。

+0

感謝您的回覆,但沒有運氣!我已經索引了連接表的外鍵。仍然需要時間。還有更多建議嗎? – user1428016

1

在同一個表中有minsdk和下載計數嗎?如果是這樣的話,在這兩者上添加索引可能會有所幫助

這可能是一個很難/不可能的查詢來快速完成。如果沒有看到完整的模式和數據,就很難具體說明,但將其分解爲幾個更容易執行的查詢可能會更快。或者像Amadeus建議的那樣,可能會使數據非規範化一點。

另一個變化是隻用它用10秒鐘生活,但要確保它總是在後臺(使用cron或類似)定期進行,用戶等待永遠不會一段時間。然後花費時間來解決它,如果/需要幾分鐘而不是幾秒鐘,否則會給用戶體驗或服務器帶來不可接受的負擔。

+0

MinSdk和downloadcount已經編入索引,但基數似乎是對於minsdk來說是小的,對於下載的計數來說是大的,那麼這樣做是否會對性能產生影響? – user1428016

+0

是的,這很可能,它們是否在同一個索引中被索引?如果是這樣,那麼請確保downloadcount是第一個(當然如果基數很高但如果你在查詢前添加'explain',MySQL會說什麼?(可能用'\ G'代替';'來完成) –

+0

1 | SIMPLE |產品|索引| PRIMARY,Minsdk,product_index_download | PRIMARY | 4 | NULL 1 | SIMPLE | product_vendors | ref | PRIMARY,productvendorindex | productvendorindex | 5 | appmall_dev.products.id | 1 |在哪裏使用;使用index | – user1428016

相關問題