0

当在以下查询中给出长时间的DateTime(查询从c#应用程序运行)时,我遇到了超时问题。表有30,000,000行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

您能提供一个完整的tbl1表格定义吗?右键单击SSMSE中的表并选择“Script as Create ...” – laylarenee

+0

添加了表定义问题。谢谢 – user2841795

+0

我提供了一个答案。请注意,添加索引会降低插入/更新时间,因为表和索引需要一起更新。索引也随着时间的推移变得分散,需要重建才能以最高的效率执行。 – laylarenee

回答

1

它很难告诉你应该不知道更多关于你的数据库,以及如何使用它使用的索引。

您可能想要将ID列更改为聚簇索引。如果ID是一个标识列,在插入新数据时,您将获得很少的页面拆分。但是,它会要求您重建表,这可能是一个问题,具体取决于您对数据库的使用情况。你会看到一些停机时间。

如果你想覆盖索引就应该是这个样子:

CREATE NONCLUSTERED INDEX [MyCoveringIndex] ON tbl1 
(
    [ReferenceNo] ASC, 
    [MinNo] ASC, 
    [DataNo] ASC, 
    [DateTime ] ASC 
) 

它没有必要列入ID作为列作为已经在clusted指数(将包含在所有其他clusted索引列索引)。然而,这会占用大量的空间(如果上面的列是int类型和datetime类型的,则在1GB的范围内)。它也会影响你插入,更新和删除表中的性能(大多数情况下)是一种消极的方式。

如果您使用Enterprice版本的SQL Server,则可以在联机模式下创建索引。在所有其他情况下,创建索引时会在表上锁定。

它也很难知道哪些其他查询是针对该表做出的。您可能想要调整索引中列的顺序以更好地匹配其他查询。

0

索引所有字段将会最快,但可能浪费大量空间。我猜想日期指数会以最少的存储容量成本提供最大的收益,因为数据可能在很长一段时间内均匀分布。如果MIN()MAX()日期是紧贴在一起,那么这将不会是有效:

CREATE NONCLUSTERED INDEX [IDX_1] ON [dbo].[tbl1] (
    [DateTime] ASC 
) 
GO 

作为一个侧面说明,您可以使用SSMSE的“显示估计的执行计划”,它会告诉你什么样的DB需要做些什么来获得你的数据。它会建议缺少索引并提供CREATE INDEX语句。这些建议可能会非常浪费,但它们会让你知道需要这么长时间的事情。该选项位于标准工具栏中,右侧有四个图标,位于“执行”。