性能调优tSQL查询计数(*)和子查询
我知道有更好的方法来完成我在这里要完成的任务。虽然查询可以正常工作,但我担心随着数据集的增长,它的性能会受到影响 我甚至不需要有人重写我的东西,如果他们愿意为我指出我应该研究的主题的方向,我将不胜感激 我试图通过这个查询返回的是处于或高于某个状态的记录数 提前感谢您的帮助 挑选 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,且c1.U_键1=或c1.U_键1为空 “状态为空” , 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,而左c1.U_键1,2>='70' “状态>70” , 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,而左c1.U_键1,2>='50' “状态>50” , 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,而左c1.U_键1,2>='30' “状态>30” , 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,而左c1.U_键1,2>=“10”性能调优tSQL查询计数(*)和子查询,tsql,count,subquery,Tsql,Count,Subquery,我知道有更好的方法来完成我在这里要完成的任务。虽然查询可以正常工作,但我担心随着数据集的增长,它的性能会受到影响 我甚至不需要有人重写我的东西,如果他们愿意为我指出我应该研究的主题的方向,我将不胜感激 我试图通过这个查询返回的是处于或高于某个状态的记录数 提前感谢您的帮助 挑选 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,且c1.U_键1=或c1.U_键1为空 “状态为空” , 选择计数* 来自表1 c1 其中c1.U_键3与“z%”不同,而左c1.U_键1,2>='70' “
作为“STATUS>10”您可以使用CASE语句将所有子查询滚动到单个查询中:
SELECT
SUM(CASE WHEN c1.U_KEY1 = '' OR c1.U_KEY1 IS NULL THEN 1 ELSE 0 END) AS 'STATUS IS EMPTY',
SUM(CASE WHEN LEFT(c1.U_KEY1,2) >= '70' THEN 1 ELSE 0 END) AS 'STATUS > 70',
SUM(CASE WHEN LEFT(c1.U_KEY1,2) >= '50' THEN 1 ELSE 0 END) AS 'STATUS > 50',
SUM(CASE WHEN LEFT(c1.U_KEY1,2) >= '30' THEN 1 ELSE 0 END) AS 'STATUS > 30',
SUM(CASE WHEN LEFT(c1.U_KEY1,2) >= '10' THEN 1 ELSE 0 END) AS 'STATUS > 10'
FROM TABLE1 c1
WHERE c1.U_KEY3 NOT LIKE 'z%'
但这可能不如单个子查询运行得快。我会像这样扭转问题:
DECLARE @t TABLE (Id INT, U_Key1 VARCHAR(4) null);
INSERT INTO @t (id,U_Key1)
VALUES
(1,null),
(2,'902'),
(3,'452'),
(4,'401'),
(5,'103'),
(6,'359'),
(7,'335'),
(8,'772'),
(9,'143'),
(10,'222'),
(11,'664'),
(12,'992'),
(13,'122'),
(14,'332'),
(15,'421'),
(16,'622'),
(17,'982'),
(18,'1234'),
(19,null),
(20,'012');
WITH A AS (
SELECT CAST(LEFT(U_Key1,2) AS INT) val FROM @t
), limits AS (
SELECT 10 limitval, 'Status >= 10' limittext
UNION ALL
SELECT 30 , 'Status >= 30'
UNION ALL
SELECT 50 , 'Status >= 50'
UNION ALL
SELECT 70 , 'Status >= 70'
), Counts AS (
SELECT 'Status is empty' Limittext, COUNT(id) Count FROM @t
WHERE U_Key1 IS null
UNION ALL
SELECT l.limittext, COUNT( A.val) Count FROM A
CROSS JOIN limits l
WHERE A.val >= l.limitval
GROUP BY l.limittext
)
SELECT * FROM Counts
这将产生以下结果:
Status is empty 2
Status >= 10 17
Status >= 30 12
Status >= 50 6
Status >= 70 4
表1上有什么索引吗?查询的运行速度可能比您想象的要快。表中有多少行?您是否尝试使用联接而不是子查询?@Tim U_键字段已编制索引。现在表中只有1200行&它运行得很好,但有可能增长到100000行。@FLICKER还没有尝试连接。你是说把桌子单独起来吗?我准备在这里犯错,但我看不出有多少改进的余地。计数查询必须扫描WHERE子句之后保留的所有记录,您实际上是在5个不同的查询中执行此操作。但对于10万张唱片,你真的关心性能吗?您希望在生产环境中多久运行一次此查询?这应该更快,因为只有一次表/索引扫描。如果有一个带有U_键1和U_键3的索引,它将是一个带有一些流聚合的单索引扫描。这并不可怕,取决于这两列的大小。@siride我知道这将是一次单表扫描,但案例陈述在我看来非常令人发指。谢谢你的评论。它们是,但它们只是可以很快计算出来的表达式。这个查询可能也是可并行的。很好!谢谢@PeterO