在下面的查询中提供长时间的DateTime时,我遇到了超时问题(查询从c#应用程序运行)。表有3000万行,ID上有非聚集索引(不是主键)。
发现没有主键,所以我最近更新了ID作为主键,它现在没有给我超时。任何人都可以帮我下面的查询为将来创建多个键的索引,如果我从这个表中删除非聚集索引并在多个列上创建?数据正在迅速增加,需要改进绩效
select
ID, ReferenceNo, MinNo, DateTime, DataNo from tbl1
where
DateTime BETWEEN '04/09/2013' AND '20/11/2013'
and ReferenceNo = 4 and MinNo = 3 and DataNo = 14 Order by ID
这是创建脚本
CREATE TABLE [dbo].[tbl1]( [ID] [int] IDENTITY(1,1) not null, [ReferenceNo] [int] not null, [MinNo] [int] not null, [DateTime] [datetime] not null, [DataNo] [int] not null, CONSTRAINT [tbl1_pk] PRIMARY KEY CLUSTERED ([ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS
= ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
答案 0 :(得分:1)
在不了解您的数据库及其使用方式的情况下,很难说出应该使用哪个索引。
您可能希望将ID列更改为聚簇索引。如果ID是标识列,则在插入新数据时将获得非常少的页面拆分。但是,它需要您重建表,这可能是一个问题,具体取决于您对数据库的使用。你会看到一些停机时间。
如果你想要一个覆盖索引,它应该是这样的:
CREATE NONCLUSTERED INDEX [MyCoveringIndex] ON tbl1
(
[ReferenceNo] ASC,
[MinNo] ASC,
[DataNo] ASC,
[DateTime ] ASC
)
它不需要将ID作为列包含在clusted索引中(clusted index列将包含在所有其他索引中)。但是,如果上面的列是int和datetime类型,则会占用大量空间(在1GB范围内)。它还会影响您在表格中的插入,更新和删除性能(大多数情况下)是否定的。
如果您使用的是SQL Server的Enterprice Edition,则可以在线模式创建索引。在所有其他情况下,在创建索引时会对表进行锁定。
很难知道对该表做出了哪些其他查询。您可能希望调整索引中列的顺序以更好地匹配其他查询。
答案 1 :(得分:0)
索引所有字段的速度最快,但可能会浪费大量空间。我猜想日期索引会以最小的存储容量成本提供最大的好处,因为数据可能在很长一段时间内均匀分布。如果MIN()MAX()日期靠近在一起,那么这将不会有效:
CREATE NONCLUSTERED INDEX [IDX_1] ON [dbo].[tbl1] (
[DateTime] ASC
)
GO
作为旁注,您可以使用SSMSE的“显示估计执行计划”,该计划将向您显示数据库需要做什么来获取您的数据。它将建议缺少索引并提供CREATE INDEX语句。这些建议可能非常浪费,但它们可以让您了解所花费的时间。此选项位于标准工具栏中,“执行”右侧有四个图标。