Как использовать результат SELECT в таблице A, чтобы ограничить SELECT таблицы B с помощью IN - PullRequest
0 голосов
/ 19 октября 2019

Я пытался использовать результат SELECT внутри оператора IN другого SELECT, но это занимает 15 минут, но если я выполняю отдельные запросы (Query1 и Query 2 ниже), я получаю результаты примерно через 2 минуты

Я пытался использовать результат SELECT внутри предложения IN другого SELECT, но он действительно медленный

        Query 1  takes 1 minute
        SELECT Id_A 
        FROM [Database]..[Table_A] 
        WHERE location = 'US'
        AND datetime_in >= DATEADD(DAY,-30,GETDATE())
        AND (
        CASE WHEN date_sent IS NULL THEN DATEDIFF(hh, datetime_in, GETDATE())
        WHEN date_sent IS NOT NULL THEN DATEDIFF(hh, datetime_in, ship_date)
        ELSE 0 END) > 120

        Query 2  takes 10 seconds
        SELECT *
        FROM [Database]..[Table_B]
        WHERE Id_B IN (HERE I INSERT MANUALLY ALL THE Table_A..Id_A)

        Query 3 taking more then 15 minutes this is the one giving me issues
        SELECT *
        FROM [Database]..[Table_B]
        WHERE Id_B IN (SELECT Id_A 
        FROM [Database]..[Table_A] 
        WHERE location = 'US'
        AND datetime_in >= DATEADD(DAY,-30,GETDATE())
        AND (CASE WHEN date_sent IS NULL 
        THEN DATEDIFF(hh, datetime_in, GETDATE())
        WHEN date_sent IS NOT NULL 
        THEN DATEDIFF(hh, datetime_in, ship_date)
        ELSE 0 END) > 120)

Я пытаюсь оптимизировать, чтобы запрос 3 мог быть выполнен и дать результаты в меньшем количестветогда 5 минут может быть?

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

В зависимости от объема данных, с которыми вы работаете, использование временных таблиц и индексов для этих таблиц может быть наиболее оптимальным подходом. Эту технику я обычно использую, когда работаю с базами данных с недостаточными индексами или когда коррелированные подзапросы дороги:

DROP TABLE IF EXISTS #ids;
SELECT Id_A
INTO #ids
FROM [Database]..[Table_A] 
WHERE location = 'US'
AND datetime_in >= DATEADD(DAY,-30,GETDATE())
AND (
    CASE WHEN date_sent IS NULL THEN DATEDIFF(hh, datetime_in, GETDATE())
    WHEN date_sent IS NOT NULL THEN DATEDIFF(hh, datetime_in, ship_date)
    ELSE 0 END
) > 120;
CREATE INDEX [IX_ids] ON #ids(Id_A);

SELECT *
FROM [Database]..[Table_B]
WHERE EXISTS (
    SELECT * FROM #ids WHERE Id_A = Id_B
);
0 голосов
/ 19 октября 2019

Похоже, вы просто пытаетесь присоединиться. Почему бы не попытаться сделать это проще, так будет намного НАСТОЛЬКО:

    SELECT TB.*
    FROM [Database]..[Table_B] AS TB
    JOIN [Database]..[Table_A] AS TA
        ON TB.Id_B = TA.Id_A
    WHERE TA.location = 'US'
        AND TA.datetime_in >= DATEADD(DAY,-30,GETDATE())
        AND (CASE WHEN TA.date_sent IS     NULL THEN DATEDIFF(hh, TA.datetime_in, GETDATE())
                  WHEN TA.date_sent IS NOT NULL THEN DATEDIFF(hh, TA.datetime_in, TA.ship_date)
    ELSE 0 END) > 120)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...