Как избежать IN (Select ...) подзапрос в хранимой процедуре MySQL - PullRequest
0 голосов
/ 09 января 2019

У меня есть сохраненная функция, которая должна сделать 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 голосов
/ 09 января 2019

вместо

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) для внешнего запроса.

...