Php 提高MySQL查询性能-可能的索引问题

Php 提高MySQL查询性能-可能的索引问题,php,mysql,sql,performance,Php,Mysql,Sql,Performance,我见过很多像我这样的问题,但读完这些问题后,我感到相当困惑 总而言之,我有一个查询,它从一个表中选择产品,并从其他表中添加更多关于产品的信息 查询: SELECT p.product_id, p.product_name, p.product_seo_url, p.product_second_name, p.product_intro_plain, p.product_price, p.produc

我见过很多像我这样的问题,但读完这些问题后,我感到相当困惑

总而言之,我有一个查询,它从一个表中选择产品,并从其他表中添加更多关于产品的信息

查询:

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秒以上

解释表明:

我假设问题在于表的索引。你能告诉我如何设置它们吗

如果您需要更多关于表格或其他信息,请告诉我

最好的, Dimitar

如果您的“ID”列实际上是数字,请删除它们周围的引号,这意味着字符串。。。即使这会导致隐含的转换。如果是数字,请将其保留为数字

正如另一个注释中所述,通过“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应该有一个索引(product_id,show_order)

您的主3w_products表应该有一个关于(man_id,product_id)的索引。。。Man_ID用于按制造商优化WHERE子句,但产品ID也用于按标准优化订单

我怀疑您的3w_manufacturers表上已经有一个有效的索引(man_id),因为它似乎是表的主键

此外,作为基于web的内容,您最好通过为“GalleryShowOrder”添加一个新列来反规范化产品表。然后,将触发器添加到Gallery表中,任何插入或更新都会将第一个“showOrder”值推回到product表中。这样,当您进行查询时,只需将另一个联接添加到产品和已知显示顺序的表中即可。如果您的多媒体资料返回1000条记录,即使您仅限于24条,它仍需要在应用order by之前获取所有记录。因此,对每个画廊图像进行1000次子查询

而你的领域选择就会变得

gal.image_filelocation, 
您的加入将添加以下内容

  LEFT JOIN 3w_products_gallery gal 
     on p.product_id = gal.product_id
    AND p.GalleryShowOrder = gal.show_order

您知道“WHERE(pcr.ctg_id='19')使pcr外部连接作为内部连接执行吗?(如果您确实想要左联接,请将条件移动到左联接的ON子句。)您在
ASC LIMIT 1)image_filelocation附近遗漏了一个逗号,
在括号内的查询结束后,这两个字段之间应该有一个逗号。如果在没有上次
LIMIT的情况下运行,查询预计返回多少行?在这里,指令
ORDER BY DESC LIMIT
只有在完成全部工作后才能进行评估。我猜某些ctg_id/man_id部分相当大。@user4419802-大约1000个结果。'table 3w_products_gallery应该在(product_id,show_order)上有一个索引-好的,它只有在给定id有一堆图像时才有用。否则,在(product_id)上纯
索引
就足够了。'main 3w\u products表应该在(man\u id,product\u id)'上有一个索引-同样,如果TS声明查询返回的行不超过1000行,那么使用复合索引优化
ORDER BY
是没有用的。还可以考虑,MySQL可能无法通过DeSC优化<代码>顺序,因为它要求“代码>索引(不支持)(MyuId,StudioToIDDEC)< /代码>(参见)