我有一个MS SQL表,行数超过2.5亿。每当我执行以下查询
SELECT COUNT(*) FROM table_name
我需要30秒才能获得输出。为什么要花这么多时间?当我查询时这会计数吗?我假设它在某个地方存储了这个信息(可能在表元数据中。我不确定表元是否存在)。
另外,我想知道这个查询是否是IO /处理器/内存密集型?
由于
答案 0 :(得分:4)
每次执行SELECT COUNT(*) from TABLE
SQL服务器实际上都会遍历表并计算所有行。要在一个或多个表上获得estemated行计数,您可以运行以下查询,该查询获取存储的信息并在1秒内返回。
SELECT OBJECT_NAME(OBJECT_ID) TableName, st.row_count
FROM sys.dm_db_partition_stats st
WHERE index_id < 2
ORDER BY st.row_count DESC
在此处详细了解http://technet.microsoft.com/en-us/library/ms187737.aspx
答案 1 :(得分:0)
不,sql server不存储此信息。它计算每个查询。但它可以缓存执行计划以强化性能。因此,如果您想快速获得结果,至少需要一个主键。
答案 2 :(得分:0)
如果您正在寻找表的近似计数,并且您的版本大于或等于SQL Server 2005,则可以使用:
SELECT t.NAME AS 'TableName'
,s.Name AS 'TableSchema'
,p.rows AS 'RowCounts'
FROM sys.tables t
INNER JOIN sys.schemas s
ON t.schema_id = s.schema_id
INNER JOIN sys.indexes i
ON t.OBJECT_ID = i.object_id
INNER JOIN sys.partitions p
ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
WHERE
t.is_ms_shipped = 0
GROUP BY
t.NAME, s.Name, p.Rows
ORDER BY
s.Name, t.Name
执行计数(*)只会占用少量内存/处理器。就数据库功能而言,它并不是那么大的操作。
答案 3 :(得分:0)
至于SQL服务器正在做什么以及它有多贵,你可以自己查看一下。在SSMS中启用查询的执行计划按钮并运行select count(*)
。您将看到服务器实际执行索引扫描(全表扫描)。 (我本来期望将PK用于此,但在我的测试用例中,它使用了其他一些非聚集索引。)。
要了解费用,请右键单击查询编辑器窗口,选择Query Options... -> Execution -> Advanced
并激活SET STATISTICS TIME
和SET STATISTICS IO
的复选框。在重新执行select语句后,“消息”选项卡将包含有关IO和计时的信息。
另请注意,就其使用的共享锁而言,选择计数(*)非常激进。为了保证结果,整个表格将被shared lock
锁定。
非常快速,无锁的替代方法是使用表的元数据。从元数据中获得的计数几乎总是准确的,但不能保证。
USE <database_name,,>
GO
SELECT ddps.row_count
FROM sys.indexes AS i
INNER JOIN sys.objects AS o
ON i.object_id = o.object_id
AND o.name = '<your_table,,>'
INNER JOIN sys.dm_db_partition_stats AS ddps
ON i.object_id = ddps.object_id
AND i.index_id = ddps.index_id
WHERE i.index_id = 1
这是SSMS模板。将其复制到查询窗口并按CTRL + SHIFT + M以获取一个对话框,询问您是否为database_name和table_name的值。