Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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
在一个包含多行的SQL表中,如何快速确定查询返回的行数是否超过1000行_Sql_Sql Server_Count - Fatal编程技术网

在一个包含多行的SQL表中,如何快速确定查询返回的行数是否超过1000行

在一个包含多行的SQL表中,如何快速确定查询返回的行数是否超过1000行,sql,sql-server,count,Sql,Sql Server,Count,注意:这是对Stack Overflow Team网站上的一个问题的重新发布,以吸引更广泛的受众 我有一个事务日志表,它有数百万条记录。链接到这些日志的许多数据项的每个项的行数可能超过10万行 我有一个要求,当日志表中存在超过1000个项目时,如果用户试图删除一个项目,则显示一条警告 我们已经确定1000个日志意味着该项目正在使用中 如果我试图简单地查询该表以查找日志行的总数,则执行查询所需的时间太长: SELECT COUNT(1) FROM History WHERE SensorID I

注意:这是对Stack Overflow Team网站上的一个问题的重新发布,以吸引更广泛的受众

我有一个事务日志表,它有数百万条记录。链接到这些日志的许多数据项的每个项的行数可能超过10万行

我有一个要求,当日志表中存在超过1000个项目时,如果用户试图删除一个项目,则显示一条警告

我们已经确定1000个日志意味着该项目正在使用中

如果我试图简单地查询该表以查找日志行的总数,则执行查询所需的时间太长:

SELECT COUNT(1) 
FROM History
WHERE SensorID IN (SELECT Id FROM Sensor WHERE DeviceId = 96)

有没有更快的方法来确定实体的日志记录是否超过1000条


注意:历史记录表在
SensorId
列上有一个索引。

您可以使用Count,而不是返回所有行并检查记录计数,但我们仍然要求数据库引擎在所有行中查找

如果要求不返回最大行数,而只是确定是否有超过X的行数,那么我要做的第一个改进就是只返回表中第一个X行的计数

因此,如果X为1000,您的应用程序逻辑不需要更改,您仍然可以确定包含999个日志和1000个以上日志的项目之间的差异

我们只需更改现有查询,选择TOP(X)行而不是计数,然后返回该结果集的计数,只选择主键或唯一索引列,以便只检查索引,而不检查基础表存储

select count(Id) FROM (
  SELECT TOP(1000)    // limit the seek that the DB engine does to the limit
         Id           // Further constrain the seek to just the indexed column 
  FROM History 
  where SensorId IN ( // this is the same filter condition as before, just re-formatted
    SELECT Id 
    FROM Sensor 
    WHERE DeviceId = 96)
) as trunk
将此查询更改为top 10000仍会提供次秒响应,但是当X=100000时,查询所用的时间几乎与原始查询一样长


如果所讨论的表具有较高的事务速率,并且执行时间的主要原因是锁争用引起的等待,则有另一种似乎是解决此类问题的“银弹”方法

如果您怀疑锁是问题所在,并且您可以接受包含未提交行的计数响应,那么您可以使用
WITH(NOLOCK)
表提示,以允许查询在
READ uncommitted
事务隔离级别有效运行

关于这个问题有很好的讨论

尽管强烈反对,但这是一个很好的例子,说明可以很容易地允许NOLOCK,这甚至是有意义的,因为删除前的计数将考虑另一个正在积极添加到日志计数中的用户或操作

经过多次尝试后,当查询1000行或10K行时,select with count解决方案仍然比使用
NOLOCK
table提示更快<但是,code>NOLOCK提供了一个机会,可以在执行相同的查询时进行最小的更改,同时仍然可以及时返回

带有
NOLOCK
的select的性能仍将随着基础结果集中的行数的增加而增加,其中,具有top with no order by子句的select的性能在超过top限制后应保持不变


您使用Count而不是返回所有行并检查记录计数是正确的,但是我们仍然要求数据库引擎在所有行中查找

如果要求不返回最大行数,而只是确定是否有超过X的行数,那么我要做的第一个改进就是只返回表中第一个X行的计数

因此,如果X为1000,您的应用程序逻辑不需要更改,您仍然可以确定包含999个日志和1000个以上日志的项目之间的差异

我们只需更改现有查询,选择TOP(X)行而不是计数,然后返回该结果集的计数,只选择主键或唯一索引列,以便只检查索引,而不检查基础表存储

select count(Id) FROM (
  SELECT TOP(1000)    // limit the seek that the DB engine does to the limit
         Id           // Further constrain the seek to just the indexed column 
  FROM History 
  where SensorId IN ( // this is the same filter condition as before, just re-formatted
    SELECT Id 
    FROM Sensor 
    WHERE DeviceId = 96)
) as trunk
将此查询更改为top 10000仍会提供次秒响应,但是当X=100000时,查询所用的时间几乎与原始查询一样长


如果所讨论的表具有较高的事务速率,并且执行时间的主要原因是锁争用引起的等待,则有另一种似乎是解决此类问题的“银弹”方法

如果您怀疑锁是问题所在,并且您可以接受包含未提交行的计数响应,那么您可以使用
WITH(NOLOCK)
表提示,以允许查询在
READ uncommitted
事务隔离级别有效运行

关于这个问题有很好的讨论

尽管强烈反对,但这是一个很好的例子,说明可以很容易地允许NOLOCK,这甚至是有意义的,因为删除前的计数将考虑另一个正在积极添加到日志计数中的用户或操作

经过多次尝试后,当查询1000行或10K行时,select with count解决方案仍然比使用
NOLOCK
table提示更快<但是,code>NOLOCK提供了一个机会,可以在执行相同的查询时进行最小的更改,同时仍然可以及时返回

带有
NOLOCK
的select的性能仍将随着基础结果集中的行数的增加而增加,其中,具有top with no order by子句的select的性能在超过top限制后应保持不变


我尝试了一个5000万条记录表,其中有66000条匹配记录。我发现使用COUNT需要0.4秒来确定COUNT>1000。