首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL性能缓慢

SQL性能缓慢
EN

Stack Overflow用户
提问于 2011-06-21 21:28:51
回答 4查看 1K关注 0票数 7

我有一个问题,如下;

代码语言:javascript
复制
 SELECT COUNT(Id) FROM Table

该表包含3300万条记录-它包含Id上的主键,没有其他索引。

查询耗时30秒。

实际的执行计划显示它使用了聚集索引扫描。

我们已经分析了该表,并发现使用此链接中显示的第一个查询http://sqlserverpedia.com/wiki/Index_Maintenance并未将其分成碎片。

关于这个查询为什么这么慢以及如何修复它,有什么想法吗?

表定义:

代码语言:javascript
复制
 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碎片是否可能是原因?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-21 21:38:28

这是一个频繁读取/插入/更新的表吗?是否存在与select并发的更新/插入活动?

我的猜测是延迟是由于争执。

在我的dev服务器上,我能够在17秒内对1.89亿行进行计数,但是没有其他东西会影响到这个表。

如果你不太担心争用或绝对准确性,你可以这样做:

exec sp_spaceused 'MyTableName',它将根据元数据给出计数。

如果您想要一个更精确的计数,但又不一定关心它是否反映了并发的DELETEINSERT活动,那么可以使用NOLOCK提示执行当前查询:

SELECT COUNT(id) FROM MyTable WITH (NOLOCK),它不会获得查询的行级锁,应该运行得更快。

票数 5
EN

Stack Overflow用户

发布于 2011-06-21 22:02:12

想法:

  • 使用SELECT COUNT(*),这对于“多少行”是正确的(根据ANSI SQL)。即使ID是主键,因此不能为空,SQL Server也会计算ID,而不是行。
  • 如果您可以接受近似计数,则使用sys.dm_db_partition_stats。在这里看我的答案:使用WITH (NOLOCK)

你可以忍受肮脏的读取Fastest way to count exact number of rows in a very large table?

  • If
票数 2
EN

Stack Overflow用户

发布于 2011-06-21 21:41:30

代码语言:javascript
复制
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子句.....

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6426032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档