查询优化,问题
Query Optimization, Issue
使用 SQL 服务器 2012;
我正在使用查询在 table 中查找增量。
我有一个存档 table,其中包含所有带有 Licenceno PK、FileID
的记录
我想知道有多少个 Licenceno 在一个 fileId 中,但不在以前的 FileID 中。
使用的代码:
Select count(*) from table where fileid = 123 and Licenceno not in (select Licenceno from table where fileid <123)
代码工作正常,但问题是一些 fileIds 的记录数与之前的相同,但需要 4 个小时,并且仍然 运行..
- 这是 table 问题吗?
- 索引不会成为问题,因为整个 table 都有
非聚集索引。
- 当我计算最新 Licenceno 的增量时,通常会发生这种情况。
- 或者查询计划是问题所在?
过去 5 天我都无法解决这个问题。
我会重写您的查询以使用 exists 子句,并添加适当的索引:
SELECT COUNT(*)(
FROM yourTable t1
WHERE
fileid = 123 AND
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.Licenseno = t1.Licenseno AND t2.fileid < 123);
(Licenseno, fileid)
上的索引可能对此处有所帮助:
CREATE INDEX idx ON yourTable (Licenseno, fileid);
你也可以按相反的顺序试试came复合索引:
CREATE INDEX idx ON yourTable (fileid, Licenseno);
为什么不使用 count(distinct)
?
select count(distinct licenseno)
from table
where fileid = 123;
对于此查询,您需要 (fileid, licenseno)
上的索引。
您按顺序思考会使逻辑复杂化 ("have I seen this licenseno
already?")。相反,您只想计算不同的值。
编辑:
对于这个问题,可以尝试两级聚合:
select count(*)
from (select licenseno, min(fileid) as min_fileid
from t
where licenseno <= 123
group by licenseno
) t
where min_fileid = 123;
相对于其他方法的性能有多好取决于 <= 123
的选择性。
您也可以使用 LAG
SELECT COUNT(*)
FROM (SELECT fileid,
LAG(fileid) OVER (PARTITION BY Licenceno ORDER BY fileid) AS prevFileID
FROM TABLE
WHERE fileid <= 123 ) D
WHERE fileid = 123
AND prevFileID IS NULL
...或聚合查询...
WITH T
AS (SELECT 1 AS Flag,
FROM TABLE
WHERE fileid <= 123
GROUP BY Licenceno
HAVING MIN(fileid) = 123 )
SELECT COUNT(*)
FROM T
使用 SQL 服务器 2012;
我正在使用查询在 table 中查找增量。 我有一个存档 table,其中包含所有带有 Licenceno PK、FileID
的记录我想知道有多少个 Licenceno 在一个 fileId 中,但不在以前的 FileID 中。
使用的代码:
Select count(*) from table where fileid = 123 and Licenceno not in (select Licenceno from table where fileid <123)
代码工作正常,但问题是一些 fileIds 的记录数与之前的相同,但需要 4 个小时,并且仍然 运行..
- 这是 table 问题吗?
- 索引不会成为问题,因为整个 table 都有 非聚集索引。
- 当我计算最新 Licenceno 的增量时,通常会发生这种情况。
- 或者查询计划是问题所在?
过去 5 天我都无法解决这个问题。
我会重写您的查询以使用 exists 子句,并添加适当的索引:
SELECT COUNT(*)(
FROM yourTable t1
WHERE
fileid = 123 AND
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.Licenseno = t1.Licenseno AND t2.fileid < 123);
(Licenseno, fileid)
上的索引可能对此处有所帮助:
CREATE INDEX idx ON yourTable (Licenseno, fileid);
你也可以按相反的顺序试试came复合索引:
CREATE INDEX idx ON yourTable (fileid, Licenseno);
为什么不使用 count(distinct)
?
select count(distinct licenseno)
from table
where fileid = 123;
对于此查询,您需要 (fileid, licenseno)
上的索引。
您按顺序思考会使逻辑复杂化 ("have I seen this licenseno
already?")。相反,您只想计算不同的值。
编辑:
对于这个问题,可以尝试两级聚合:
select count(*)
from (select licenseno, min(fileid) as min_fileid
from t
where licenseno <= 123
group by licenseno
) t
where min_fileid = 123;
相对于其他方法的性能有多好取决于 <= 123
的选择性。
您也可以使用 LAG
SELECT COUNT(*)
FROM (SELECT fileid,
LAG(fileid) OVER (PARTITION BY Licenceno ORDER BY fileid) AS prevFileID
FROM TABLE
WHERE fileid <= 123 ) D
WHERE fileid = 123
AND prevFileID IS NULL
...或聚合查询...
WITH T
AS (SELECT 1 AS Flag,
FROM TABLE
WHERE fileid <= 123
GROUP BY Licenceno
HAVING MIN(fileid) = 123 )
SELECT COUNT(*)
FROM T