Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
性能调优tSQL查询计数(*)和子查询_Tsql_Count_Subquery - Fatal编程技术网

性能调优tSQL查询计数(*)和子查询

性能调优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' “

我知道有更好的方法来完成我在这里要完成的任务。虽然查询可以正常工作,但我担心随着数据集的增长,它的性能会受到影响

我甚至不需要有人重写我的东西,如果他们愿意为我指出我应该研究的主题的方向,我将不胜感激

我试图通过这个查询返回的是处于或高于某个状态的记录数

提前感谢您的帮助

挑选 选择计数* 来自表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”
作为“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