如何解决提高 sql 查询性能以使用相同的列比较 2 个不同的行而不是加入另一个表
我有一张名为 Status
的表。在此表中,每个 A
可以有 2 条记录状态为“O
”和“c_number
”。每个 c_number
的许多记录都在 NUMBER
表中。 record_date
表中带有“c_number's
”的O
记录的Status
字段必须大于带有“{”的record_date
记录的c_number's
{1}} 和 A'
必须在指定的日期之间。此外,record_date
在 c_number's
表中应该有一个 record_status
为 '1
' 的记录。为此,我准备了以下查询。如何在没有索引的情况下提高查询性能?每个表都有数百万条记录。
NUMBER
解决方法
可以使用条件窗口函数得到自己需要的结果,不需要自连接。
进一步说明:
- 不要不要使用
NOLOCK
,除非您不介意不正确的结果。后果很严重,只有在你真正知道自己在做什么时才使用它 - 在日期上使用半开区间代替
BETWEEN
,而不是>= AND <
。这意味着您无需在一天中的最后一毫秒内搞砸 - 在很多情况下,
EXISTS
或IN
半连接比不同连接更好,并且让编译器可以更自由地重新排列查询
SELECT
d.id,d.c_number,d.record_date,oRecordDate
FROM (
SELECT *,oRecordDate = MIN(CASE WHEN d.record_status = 'O' THEN d.record_date END) OVER
(PARTITION BY d.c_number ORDER BY d.record_date ROWS UNBOUNDED FOLLOWING)
FROM dbo.STATUS d
) d
WHERE d.c_number IN (
SELECT cc.c_number
FROM dbo.NUMBERS cc
WHERE
cc.status_flag = '1'
AND cc.record_date >= '2021-07-01'
AND cc.record_date < '2021-07-25'
)
AND d.record_date >= '2021-07-01'
AND d.record_date < '2021-07-25'
AND d.record_status = 'A';
,
您只需要确定 NUMBERS
表中是否有任何可用记录,在这种情况下,您不需要加入和使用 DISTINCT
(这是一项代价高昂的操作)。>
相反,您使用 EXISTS
,这就足够了。
检查以下查询一次
DECLARE @StartDate DATETIME = '2021-07-01 00:00:00.000'
DECLARE @EndDate DATETIME = '2021-07-01 00:00:00.000'
SELECT a_status.id,a_status.c_number,a_status.record_date,o_status.record_date
FROM dbo.STATUS (NOLOCK) a_status
INNER JOIN dbo.STATUS (NOLOCK) o_status ON o_status.c_number = a_status.c_number
AND o_status.record_status = 'O'
AND a_status.record_status = 'A'
AND o_status.record_date >= a_status.record_date
WHERE a_status.record_date BETWEEN @StartDate
AND @EndDate
AND EXISTS (
SELECT 1
FROM dbo.NUMBERS(NOLOCK) n
WHERE n.status_flag = '1'
AND n.record_date BETWEEN @StartDate
AND @EndDate
AND n.c_number = a_status.c_number
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。