首页 > 解决方案 > 如何使用表 A 中 SELECT 的结果,使用 IN 限制表 B 的 SELECT

问题描述

我尝试在另一个 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 分钟的时间内给出结果?

标签: sqlsql-server

解决方案


根据您使用的数据量,在这些表上使用临时表和索引可能是最佳方法。当我使用索引不足的数据库或相关子查询很昂贵的数据库时,我倾向于经常使用这种技术:

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
);

推荐阅读