Mikael Eriksson 很好地解释了为什么第一个查询很快:
SQL server 将其优化为:
if exists(select * from BookChapters)
. 所以它会寻找一行的存在,而不是计算表中的所有行。
对于其他两个查询,SQL Server 将使用以下规则。要执行类似的查询SELECT COUNT(*)
,SQL Server 将使用最窄的
非聚集索引来计算行数。如果表没有任何非聚集索引,则必须扫描表。
此外,如果您的表具有聚集索引,您可以使用以下查询更快地获得计数(借自此站点Get Row Counts Fast!)
--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
它使用 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
您应该会发现无论您有多少张桌子,它都会很快返回。
如果您使用的是 SQL 2000,您仍然可以使用 sysindexes 表来获取数字。
select max(ROWS)
from sysindexes
where id = object_id(’YourTable’)
根据 SQL 更新 sysindexes 表的频率,这个数字可能略有偏差,但它通常是正确的(或至少足够接近)。