dan*_*iao 35 sql sql-server performance count
我有一个超过2000万行的SQL表BookChapters.它有一个集群主键(bookChapterID),没有任何其他键或索引.运行以下查询需要几毫秒
if (select count(*) from BookChapters) = 0
...
Run Code Online (Sandbox Code Playgroud)
但是,当我这样改变它需要10多分钟
if (select count(*) from BookChapters) = 1
...
Run Code Online (Sandbox Code Playgroud)
要么
if (select count(*) from BookChapters) > 1
...
Run Code Online (Sandbox Code Playgroud)
这是为什么?我怎样才能select count(*)更快地执行?
Ale*_*kov 53
Mikael Eriksson对第一个查询速度快的原因有一个很好的解释:
SQL服务器将其优化为:
if exists(select * from BookChapters).因此,它寻找存在一行而不是计算表中的所有行.
对于其他两个查询,SQL Server将使用以下规则.要执行类似的查询SELECT COUNT(*),SQL Server将使用最窄的
非聚集索引来计算行数.如果表没有任何非聚集索引,则必须扫描该表.
此外,如果您的表具有聚集索引,您可以使用以下查询更快地获得计数(从此站点借用获取行计数快!)
--SQL Server 2005/2008
SELECT OBJECT_NAME(i.id) [Table_Name], i.rowcnt [Row_Count]
FROM sys.sysindexes i WITH (NOLOCK)
WHERE i.indid in (0,1)
ORDER BY i.rowcnt desc
--SQL Server 2000
SELECT OBJECT_NAME(i.id) [Table_Name], i.rows [Row_Count]
FROM sysindexes i (NOLOCK)
WHERE i.indid in (0,1)
ORDER BY i.rows desc
Run Code Online (Sandbox Code Playgroud)
它使用sysindexes系统表.您可以在此处找到更多信息SQL Server 2000,SQL Server 2005,SQL Server 2008,SQL Server 2012
这是另一个链接为什么我的SELECT COUNT(*)运行如此之慢?与另一种解决方案 它显示了当您右键单击表并选择属性时Microsoft用于快速显示行数的技术.
select sum (spart.rows)
from sys.partitions spart
where spart.object_id = object_id(’YourTable’)
and spart.index_id < 2
Run Code Online (Sandbox Code Playgroud)
你会发现无论你有多少桌子,这都会很快恢复.
如果您仍在使用SQL 2000,则可以使用sysindexes表来获取数字.
select max(ROWS)
from sysindexes
where id = object_id(’YourTable’)
Run Code Online (Sandbox Code Playgroud)
这个数字可能略有偏差,具体取决于SQL更新sysindexes表的频率,但它通常是相同的(或者至少足够接近).
ehs*_*net 12
如果您只想知道行数,请尝试此操作:
exec sp_spaceused [TABLE_NAME]
Run Code Online (Sandbox Code Playgroud)
如果您查看查询的执行计划,您将看到正在发生的事情.
if (select count(*) from BookChapters) = 0查询优化器将您的第一个查询识别为与查询优化器相同if exists(select * from BookChapters).如果存在至少一行,则SQL Server知道表达式为true,因此它会查找是否存在一行而不是计算表中的所有行.
对于您的其他查询,它不能那么聪明,并且必须先计算表中的行数,然后才能确定表达式的计算结果是true还是false.
你考虑过查询select count(BookChapterId) from BookChapterTable 吗?- 其中`BookChapterId 是非聚集索引.这应该使它运行得更快.
根据表如何使用和行访问,查询对非聚集索引可能是关键的一点:我只是把一些点从MDSN:
| 归档时间: |
|
| 查看次数: |
54828 次 |
| 最近记录: |