2010-05-23 40 views
0

我有一個搜索需要10秒+執行!請記住,它也在數據庫中搜索超過200,000種產品。我在這裏發佈瞭解釋和MySQL查詢。這個MySQL quert有什麼問題嗎?需要10秒+加載

1 SIMPLE p ref PRIMARY,products_status,prod_prodid_status,product... products_status 1 const 9048 Using where; Using temporary; Using filesort 
1 SIMPLE v ref PRIMARY,vendors_id,vendors_vendorid vendors_vendorid 4 rhinomar_rhinomartnew.p.vendors_id 1 
1 SIMPLE s ref products_id products_id 4 rhinomar_rhinomartnew.p.products_id 1 
1 SIMPLE pd ref PRIMARY,products,prod_desc_prodid_prodname prod_desc_prodid_prodname 4 rhinomar_rhinomartnew.p.products_id 1 
1 SIMPLE p2c ref PRIMARY,ptc_catidx PRIMARY 4 rhinomar_rhinomartnew.p.products_id 1 Using where; Using index 
1 SIMPLE c eq_ref PRIMARY PRIMARY 4 rhinomar_rhinomartnew.p2c.categories_id 1 Using where 

MySQL查詢:

Select p.products_id, p.products_image, p.products_price, p.products_weight, 
     p.products_unit_quantity, 
     s.specials_new_products_price, s.status, 
     pd.products_name, pd.products_img_alt 
From products p 
Left Join vendors v On v.vendors_id = p.vendors_id 
Left Join specials s On s.products_id = p.products_id 
Left Join products_description pd On pd.products_id = p.products_id 
Left Join products_to_categories p2c On p2c.products_id = p.products_id 
Left Join categories c On c.categories_id = p2c.categories_id 
Where 
( pd.products_name Like '%apparel%' 
    Or p2c.categories_id In (773, 132, 135, 136, 119, 122, 124, 125, 126, 1749, 1753, 
          1747, 123, 127, 130, 131, 178, 137, 140, 164, 165, 166, 
          167, 168, 169, 832, 2045) 
    Or p.products_id = 'apparel' 
    Or p.products_model = 'apparel' 
    Or Concat(v.vendors_prefix, '-') = 'apparel' 
    Or Concat(v.vendors_prefix, '-', p.products_id) = 'apparel' 
) 
And p.products_status = '1' 
And c.categories_status = '1' 
Group By p.products_id 
Order By pd.products_name 
+1

在你的情況下,'apparel'代表什麼?搜索'Concat(v.vendors_prefix,' - ')='apparel''不會返回任何內容,因爲'apparel'不會以連字符結尾。你真的需要所有的「左連接」而不是「連接」嗎? – 2010-05-23 06:48:12

+0

您提到查詢超過200,000種產品,但您獲得了多少結果?你不錯過某處的連接? – 2010-05-23 20:16:36

+0

彼得你是對的!除了一個以外,我除掉了所有剩下的連接,所以這似乎加快了它的速度。此外,我將WHERE和AND子句中的所有列編入索引,並且查詢似乎始終在2.2秒內運行。 :-) – 2010-05-23 22:38:33

回答

0

看來你只使用products_description表,以便檢索products_nameproducts_img_alt,是不是有可能有products表裏面這兩列?

+0

這將花費太多時間通過編碼。這就是osCommerce如何構建他們的數據庫。 – 2010-05-23 22:43:27

-1

那麼,我會說加載這麼長時間的原因是因爲它必須在磁盤上創建一個臨時表。 (因此使用臨時;使用filesort;)

我最近遇到了同樣的問題,當我使用「WHERE id IN(1,2,3等)」子句。你可以刪除它只是爲了測試它是否阻止了filesort?

+0

這是'GROUP BY'導致filesort – 2010-05-23 19:37:59

+0

在我的情況下,它不是。我刪除了所有的ORDER BY和GROUP BY子句。但是,我沒有注意到OP的查詢中的GROUP BY,你說得對,更有可能是因爲它造成的。 – 2010-05-23 20:06:42

0

由於您的EXPLAIN顯示了您正在選擇的products_status索引,我猜測它是某種標誌,顯示產品是否處於活動狀態?這裏的粒度可能不是很多,所以你可能沒有從中得到很多幫助。

我不知道MySQL是否已經優化了這一點,但是您應該在您的第一個WHERE謂詞中訂購商品 - (x OR y OR z)匹配的可能性以及降低評估費用。具體而言,p2c.category_id IN (...)應位於短語的開頭,因爲它可以使用categories上的索引。 CONCAT應該是短語中的最後一個,並且LIKE應該在中間。

通常一個UNION是分裂的OR短語的最佳方式,但因爲你的OR列表的一些元素是昂貴的功能,這可能不是你的最佳選擇。

您應該考慮您是否可以在某種程度上使數據標準化,並閱讀Peter Lang的評論以獲得一些良好的觀察結果。