我看过像我这样的很多问题,但在读完这些问题后,我感到非常困惑。
总结一下 - 我有一个查询从表中选择产品,并从其他表中添加有关它们的更多信息。
查询:
SELECT
p.product_id,
p.product_name,
p.product_seo_url,
p.product_second_name,
p.product_intro_plain,
p.product_price,
p.product_price_promo,
p.product_promo_expire_date,
p.product_views,
p.product_code,
p.product_exquisite,
p.product_rating,
p.product_votes,
p.product_date_added,
p.product_returned,
p.product_price_returned,
( SELECT gal.image_filelocation
FROM 3w_products_gallery gal
WHERE gal.product_id = p.product_id
ORDER BY show_order ASC
LIMIT 1 ) image_filelocation,
m.man_image_location,
m.man_name,
m.man_seo_url
FROM
3w_products p
LEFT JOIN 3w_manufacturers m
ON p.man_id = m.man_id
LEFT JOIN 3w_products_cat_rel pcr
ON p.product_id = pcr.product_id
WHERE
pcr.ctg_id = '19'
AND p.man_id = '190'
ORDER BY
p.product_id DESC
LIMIT
0, 24
发生的奇怪事情是查询有时会执行0.001秒。有时候超过30秒。
EXPLAIN显示: http://i.stack.imgur.com/ZNtBX.png
我认为问题在于表的索引。你能告诉我如何设置它们吗?
如果您需要有关表格或其他任何信息,请告诉我们。
最佳, 迪米塔尔
答案 0 :(得分:0)
如果您的“ID”列实际上是数字,请删除它们周围的引号,这意味着字符串......即使它会隐含转换。如果是数字,请保持数字。
正如评论中的另一篇所述,您的LEFT JOIN通过“pcr”别名及其WHERE子句中的条件将其转换为内部联接。
FROM
3w_products p
LEFT JOIN 3w_manufacturers m
ON p.man_id = m.man_id
LEFT JOIN 3w_products_cat_rel pcr
ON p.product_id = pcr.product_id
AND pcr.ctg_id = 19
WHERE
AND p.man_id = 190
字段级查询可能会导致性能下降,因为每个字段的选择(图像位置)对每个记录都执行一次。为了至少帮助这个性能,表3w_products_gallery应该有一个索引ON(product_id,show_order)
您的主要3w_products表应该有一个索引(man_id,product_id)... Man_ID用于按制造商优化WHERE子句,还有产品ID以帮助优化ORDER BY标准。
你的3w_manufacturers表,我怀疑在(man_id)上已经有一个有效的索引,因为它似乎是该表的主键。
此外,作为基于网络的内容,您可能最好通过为“GalleryShowOrder”添加一个新列来对您的产品表进行DE-NORMALIZE。然后,向Gallery表添加一个触发器,任何插入或更新都会将第一个“showOrder”值推回到product表中。这样,当您查询时,您只需在产品和已知显示顺序上向该表添加另一个连接。如果您的图库返回1000条记录,即使您只限制为24条记录,它仍然需要在应用订单之前获取所有记录。因此每个图库图像的1000个子查询。
您的字段选择将变为
gal.image_filelocation,
你的JOIN会添加以下内容
LEFT JOIN 3w_products_gallery gal
on p.product_id = gal.product_id
AND p.GalleryShowOrder = gal.show_order