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

时间:2019-01-09 13:30:51

标签: 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 (select)

速度慢
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;

1 个答案:

答案 0 :(得分:0)

代替

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是一个变量,可能是该过程的参数。如果不使用正确的表别名对其进行限定。)

inventory (asin, sku)上创建索引以支持它。

要考虑的另一个索引应位于外部查询的inventory (marketplace_id, date, asin)上。