sql - 提高 sql 查询性能以比较使用同一列的 2 个不同行而不是加入另一个表
问题描述
我有一张桌子叫Status
. 在此表中,可以有 2 条记录,每个记录的状态为“ A
”和“ O
” c_number
。每个的许多记录c_number
都在NUMBER
表中。表中带' 'record_date
的记录字段必须大于带'的记录的字段,并且必须在指定日期之间。另外,表中应该有一条带有' ''的记录。为此,我准备了以下查询。如何在没有索引的情况下提高查询性能?每个表都有数百万条记录。c_number's
O
Status
record_date
c_number's
A'
record_date
c_number's
record_status
1
NUMBER
SELECT
d.id,
d.c_number,
d.record_date,
dup.record_date
FROM
dbo.STATUS (nolock) as d
INNER JOIN
(SELECT DISTINCT
c_number,
record_date
FROM
dbo.STATUS (NOLOCK)
WHERE
record_status = 'O'
and record_date between '2021-07-01 00:00:00.000'
and '2021-07-24 23:59:59.00') dup ON dup.c_number = d.c_number
AND d.record_status = 'A'
AND dup.record_date >= d.record_date
INNER JOIN
(SELECT DISTINCT c_number
FROM dbo.NUMBERS (NOLOCK)
WHERE
status_flag = '1'
AND record_date between '2021-07-01 00:00:00.000'
AND '2021-07-24 23:59:59.00') cc ON cc.c_number = d.c_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';
推荐阅读
- go - 在切片上调用 len() 有多快?
- c++ - 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
- windows - gsutil rsync 排除模式不适用于 Windows Powershell
- c# - 重新启动我的应用程序后,ISharedPreferences 存储的字符串正在更新
- javascript - 如何在 .append() 函数中的 $.each 中添加 html 元素?
- x86 - How does a PCIe device appear bootable to the BIOS/UEFI?
- javascript - 我如何正确清除“setTimeout”JavaScript
- python - 用户注销 Django 时如何删除会话?
- python - 找到两个节点并在它们之间创建关系(python中的neo4j)
- postman - 如何将邮递员响应内容类型:- text/plain 存储到变量中?