【发布时间】:2010-06-14 13:13:40
【问题描述】:
以下是表格的脚本。从此表中访问数据太慢了。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Emails](
[id] [int] IDENTITY(1,1) NOT NULL,
[datecreated] [datetime] NULL CONSTRAINT [DF_Emails_datecreated]
DEFAULT (getdate()),
[UID] [nvarchar](250) COLLATE Latin1_General_CI_AS NULL,
[From] [nvarchar](100) COLLATE Latin1_General_CI_AS NULL,
[To] [nvarchar](100) COLLATE Latin1_General_CI_AS NULL,
[Subject] [nvarchar](max) COLLATE Latin1_General_CI_AS NULL,
[Body] [nvarchar](max) COLLATE Latin1_General_CI_AS NULL,
[HTML] [nvarchar](max) COLLATE Latin1_General_CI_AS NULL,
[AttachmentCount] [int] NULL,
[Dated] [datetime] NULL
) ON [PRIMARY]
以下查询需要 50 秒来获取数据。
select id, datecreated, UID, [From], [To], Subject, AttachmentCount,
Dated from emails
如果我在选择中包含 Body 和 Html,那么时间会更糟。
索引开启:
- id 唯一集群
- 来自非唯一非集群
- 到非唯一非集群
Tables 目前有 180000+ 条记录。
每个月可能有 100,000 条记录,所以随着时间的推移,这将变得越来越慢。
将数据分成两个表会解决问题吗? 应该还有哪些其他索引?
【问题讨论】:
-
等一下:检索 18 万条记录需要 50 秒?为什么要检索 180K 记录?你用它们做什么?为什么50秒这么长?这不像人类可以在屏幕上处理 18 万条记录。所以我的问题是你真的需要所有的记录,还是你的例子中省略了一个 WHERE 子句?
-
我不认为索引会起作用,因为你没有 where 子句。无论如何,您都在进行全表扫描。
-
为什么需要从表中检索所有记录?你不能使用一些限制性子句吗?
-
你说得对,我跳过了 where 子句,因为我认为获取这些记录需要 5 到 6 秒。为什么要 5 到 6 秒,因为当我只在 'id' 上获取时,它只需要 2 秒,所以这个差异太大了。
-
想一想。获取所有记录需要大量 IO - 不需要 5-6 秒。 where 子句绝对是至关重要的 - 将您的数据需求确定为您此刻真正需要的数据。通过 ID 获取应该花费很少的时间。百分之一秒或更短。
标签: sql sql-server-2005 tsql query-optimization