mysql - 如何避免mysql存储过程中的IN(Select...)子查询

标签 mysql stored-procedures subquery

我有一个存储函数,需要执行select ... from ... where foo IN (select ...)

问题是,与执行简单的 where = ... 相比,它慢得令人难以置信

由于已知这种语法很慢,是否有任何可能的方法将结果存储到变量中,然后在 IN () 条件中使用该变量?我不知道如何将多行查询存储到变量中。

这是使用变量的快速相等。 (但是错误的 b/c 它只执行 1 个值而不是多个值)

BEGIN

    DECLARE average DECIMAL(10,4);
    DECLARE skuAsin VARCHAR(30);

    SET skuAsin = (SELECT DISTINCT asin FROM inventory WHERE sku = aSku ORDER BY id DESC LIMIT 1);

    SET average = (
        SELECT  avg(unitsByDay) FROM (
            SELECT i.date, sum(units_ordered) as unitsByDay from inventory i
            WHERE
                i.asin = skuAsin &&
                i.marketplace_id = mid &&
                i.date between d1 and d2
            GROUP BY date
        ) as vel
    );

    RETURN average;

END;

这是使用IN(选择)的慢速

BEGIN

    DECLARE average DECIMAL(10,4);

    SET average = (
        SELECT  avg(unitsByDay) FROM (
            SELECT i.date, sum(units_ordered) as unitsByDay from inventory i
            WHERE
                i.asin IN (SELECT DISTINCT asin FROM inventory WHERE sku = aSku) &&
                i.marketplace_id = mid &&
                i.date between d1 and d2
            GROUP BY date
        ) as vel
    );

    RETURN average;

END;

最佳答案

而不是

i.asin IN (SELECT DISTINCT asin FROM inventory WHERE sku = aSku)

尝试使用EXISTS

EXISTS (SELECT *
               FROM inventory ii
               WHERE ii.asin = i.asin
                     AND ii.sku = asku)

(我假设 asku 是一个变量,可能是过程的参数。如果没有使用正确的表别名来限定它。)

库存(asin、sku) 上创建索引以支持它。

要考虑的另一个索引是外部查询的inventory (marketplace_id, date, asin)

关于mysql - 如何避免mysql存储过程中的IN(Select...)子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54111323/

相关文章:

mysql请求如果不存在

mysql - 在带有 OR 条件的 LEFT JOIN 中使用索引

sql-server - 获取存储过程所在的数据库名称

sql - 如何在 Where 子句中使用别名?

c# - Ado.net ExecuteScalar() 返回 null

php - Mysql中条件检查之间有多个条件吗?有什么办法可以优化这个查询吗?

MySQL SUM 返回错误值

java - 将 mysql 日期解析为 ZonedDateTime

php - 使用 laravel 查询构建器构建查询

mysql - 奇怪的 SQL 代码 : Why do they use a subquery instead of join?