我有一个问题,如下;
SELECT COUNT(Id) FROM Table该表包含3300万条记录-它包含Id上的主键,没有其他索引。
查询耗时30秒。
实际的执行计划显示它使用了聚集索引扫描。
我们已经分析了该表,并发现使用此链接中显示的第一个查询http://sqlserverpedia.com/wiki/Index_Maintenance并未将其分成碎片。
关于这个查询为什么这么慢以及如何修复它,有什么想法吗?
表定义:
CREATE TABLE [dbo].[DbConversation](
[ConversationID] [int] IDENTITY(1,1) NOT NULL,
[ConversationGroupID] [int] NOT NULL,
[InsideIP] [uniqueidentifier] NOT NULL,
[OutsideIP] [uniqueidentifier] NOT NULL,
[ServerPort] [int] NOT NULL,
[BytesOutbound] [bigint] NOT NULL,
[BytesInbound] [bigint] NOT NULL,
[ServerOutside] [bit] NOT NULL,
[LastFlowTime] [datetime] NOT NULL,
[LastClientPort] [int] NOT NULL,
[Protocol] [tinyint] NOT NULL,
[TypeOfService] [tinyint] NOT NULL,
CONSTRAINT [PK_Conversation_1] PRIMARY KEY CLUSTERED
(
[ConversationID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO我注意到的一件事是,数据库被设置为以1Mb区块为单位增长。
这是一个活的系统,所以我们限制了我们可以玩的东西--有什么想法吗?
更新:
好的-我们已经通过在适当的列上添加新的非聚集索引来提高实际查询的性能,所以这不再是一个关键问题。
SELECT COUNT仍然很慢--用NOLOCK提示尝试过--没有区别。
我们都认为这与设置为1Mb的Autogrowth有关,而不是一个更大的数字,但令人惊讶的是它有这种效果。磁盘上的MDF碎片是否可能是原因?
发布于 2011-06-21 21:38:28
这是一个频繁读取/插入/更新的表吗?是否存在与select并发的更新/插入活动?
我的猜测是延迟是由于争执。
在我的dev服务器上,我能够在17秒内对1.89亿行进行计数,但是没有其他东西会影响到这个表。
如果你不太担心争用或绝对准确性,你可以这样做:
exec sp_spaceused 'MyTableName',它将根据元数据给出计数。
如果您想要一个更精确的计数,但又不一定关心它是否反映了并发的DELETE或INSERT活动,那么可以使用NOLOCK提示执行当前查询:
SELECT COUNT(id) FROM MyTable WITH (NOLOCK),它不会获得查询的行级锁,应该运行得更快。
发布于 2011-06-21 22:02:12
想法:
SELECT COUNT(*),这对于“多少行”是正确的(根据ANSI SQL)。即使ID是主键,因此不能为空,SQL Server也会计算ID,而不是行。WITH (NOLOCK)你可以忍受肮脏的读取Fastest way to count exact number of rows in a very large table?
发布于 2011-06-21 21:41:30
use [DatabaseName]
select tbl.name, dd.rows from sysindexes dd
inner join sysobjects tbl on dd.id = tbl.id where dd.indid < 2 and tbl.xtype = 'U'
select sum(dd.rows)from sysindexes dd
inner join sysobjects tbl on dd.id = tbl.id where dd.indid < 2 and tbl.xtype = 'U' 通过使用这些查询,您可以在0-5秒内获取所有表的计数
根据需要使用where子句.....
https://stackoverflow.com/questions/6426032
复制相似问题