带子查询的慢速SQL查询和子查询

时间:2018-09-04 11:15:41

标签: mysql sql sql-order-by sqlperformance

以下是查询:

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
    ) 

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

表结构:

目录:这是主产品目录表

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

products:存储产品型号(尺寸选项)

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

列表::存储产品列表,一个“产品尺寸”选项可以包含多个具有不同价格的产品列表。

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

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

它显示每个列表和大小的最低价格。

2 个答案:

答案 0 :(得分:0)

由于子查询实际上没有执行任何操作,请尝试执行此操作。如果这不起作用,请发布explain语句的输出,并避免使用表别名(如“ 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

答案 1 :(得分:0)

我能够解决这个问题。

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

我已经使用最小(价格)和按大小分组以获取最小价格清单。

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

谢谢!