【问题标题】:Slow SQL Query with Sub Query with Order By带有子查询的慢速 SQL 查询和 Order By
【发布时间】:2018-09-04 11:15:41
【问题描述】:

这是查询:

SELECT product.catalog_product_id AS catalog_id, listing.id AS listing_id, 
    product.size AS size, 0 AS amount, 
    listing.list_price AS price, 
    listing.created_at AS created_date 
FROM product
INNER JOIN listing ON listing.product_id = product.id 
WHERE product.catalog_product_id = XXXX
    AND listing.id = (
        SELECT l.id
        FROM listing l
        INNER JOIN product i ON l.product_id = i.id
        WHERE i.size = product.size AND i.catalog_product_id = XXXX
        ORDER BY l.list_price ASC, l.created_at ASC
        LIMIT 1
    ) 

Sub Query 是获取最低价格的列表 ID。子查询因 Order by 而变慢。我已经创建了索引,仍然需要 5-6 秒。

表结构:

catalog:这是主产品目录表

Catalog
-------
id
sku
name
description

products : 存储产品变体(尺寸选项)

Products
--------
id
catalog_id
size 

listing table:: 存储产品listing,一个产品尺寸选项可以有多个不同价格的产品listing。

listing
---------
id
product_id
list_price
created_at

输出: http://prntscr.com/kqh7fg

它显示每个列表和尺寸的最低价格。

【问题讨论】:

  • 你在外部查询和子查询中重复相同的连接,在相同的两个表之间,我有点失望。您能否提供一些示例数据来显示您在此处尝试执行的操作?
  • 好的,让我在这里添加一些示例数据。
  • 请包括解释的输出
  • 更新了表结构和输出截图。

标签: mysql sql sql-order-by sqlperformance


【解决方案1】:

由于您的子查询实际上并没有做任何事情,请试试这个。如果这不起作用,请发布解释语句的输出并避免使用表别名,如“l”和“i”。它真的很难阅读,而且出错的机会增加了很多(例如,您出于某种原因加入了 'product.size' 本身)。

SELECT
            product.catalog_product_id AS catalog_id,
            listing.id AS listing_id, 
            product.size AS size, 0 AS amount, 
            listing.list_price AS price, 
            listing.created_at AS created_date 
FROM        product
INNER JOIN  listing
    ON      listing.product_id = product.id 
WHERE       product.catalog_product_id = ?
ORDER BY    listing.list_price ASC,
            listing.created_at ASC
LIMIT       1

【讨论】:

    【解决方案2】:

    我能够解决这个问题。

    SELECT product.catalog_product_id AS catalog_id, listing.id AS listing_id, 
    product.size AS size,
    listing.list_price AS price, 
    listing.created_at AS created_date
    FROM product
    INNER JOIN listing ON listing.product_id = product.id
    AND product.catalog_product_id = XXXX 
    AND listing.id IN 
    (
    SELECT MIN(l.id)
    FROM listing l
    INNER JOIN product i ON l.product_id = i.id
    WHERE i.catalog_product_id = XXXX 
    AND list_price = (
    SELECT MIN(list_price)
    FROM listing l
    INNER JOIN product it ON l.product_id = it.id
    WHERE it.catalog_product_id = XXXX AND it.size = i.size
    )
    GROUP BY i.size
    )
    

    而不是使用:

    ORDER BY l.list_price ASC, l.created_at ASC  LIMIT 1
    

    我使用 Min(Price) 和 Group By Size 来获取最低价格列表。

    查询性能从 5 秒提高到 0.5 秒

    谢谢!

    【讨论】:

      猜你喜欢
      • 2011-07-19
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多