这个MySQL查询有什么问题吗?加载需要10秒钟

时间:2010-05-23 06:09:34

标签: sql mysql query-optimization

我的搜索需要10秒+才能执行!请记住,它还在数据库中搜索超过200,000种产品。我在这里发布了explain和MySQL查询。

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

3 个答案:

答案 0 :(得分:0)

您似乎只使用products_description表来检索products_nameproducts_img_alt,是不是可以在products表中包含这两列?

答案 1 :(得分:0)

正如您的EXPLAIN向您展示的那样,它是被选中的products_status索引,我猜是某种标志,表明产品是否有效?那里可能没有太多的粒度,所以你可能没有得到很多帮助。

我不知道MySQL是否已经对此进行了优化,但是您应该在第一个WHERE谓词 - (x OR y OR z)中按照匹配的可能性和降低的评估费用来订购项目。具体来说,p2c.category_id IN (...)应位于短语的开头,因为它可以使用categories上的索引。 CONCAT应该在短语中排在最后,而LIKE应位于中间位置。

通常UNION是分割OR词组的最佳方法,但由于OR列表中的某些元素是昂贵的功能,这可能不是您的最佳选择

您应该考虑是否可以在某种程度上规范化您的数据,并阅读Peter Lang的评论以获得一些好的观察结果。

答案 2 :(得分:-1)

好吧,我会说加载这么长时间的原因是因为它必须在磁盘上创建一个临时表。 (因此使用临时;使用filesort;)

当我使用“WHERE id IN(1,2,3,etc)”子句时,我最近遇到了同样的问题。你可以删除它只是为了测试它是否会阻止文件输出吗?