SQL性能建议

时间:2018-03-21 13:52:12

标签: sql-server

我知道这可能是一个棘手的问题,而且它在很大程度上取决于背景。

我有一个包含大约1000万行的表的数据库(每行包含4个varchar)。 字段上有一个非聚集的索引(varchar)用于where。

我有点困惑,因为在使用索引列上的where选择一行时,大约需要一秒钟才能结束。

任何改善此响应时间的建议? 索引聚类会在这里成为一个好的解决方案吗?

以下是表格定义:

CREATE TABLE [dbo].[MYTABLE](
[ID] [uniqueidentifier] NOT NULL DEFAULT (newid()),
[CreationDate] [datetime] NOT NULL DEFAULT (getdate()),
[UpdateDate] [datetime] NULL,
[FIELD1] [varchar](9) NOT NULL,
[FIELD2] [varchar](max) NOT NULL,
[FIELD3] [varchar](1) NULL,
[FIELD4] [varchar](4) NOT NULL,
CONSTRAINT [PK_MYTABLE] 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] TEXTIMAGE_ON [PRIMARY]

这是索引定义:

CREATE UNIQUE NONCLUSTERED INDEX [IX_FIELD1] ON [dbo].[MYTABLE]
(
[FIELD1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

这是我使用的查询(非常基本):

SELECT * FROM MYTABLE WHERE FIELD1 = 'DATA'

2 个答案:

答案 0 :(得分:1)

如果您确定WHERE子句中使用的列是唯一的,则可以在该列上创建UNIQUE CLUSTERED INDEX

如果该列中的值不唯一,则可以实施COVERING INDEXES。例如,如果您有此索引:

CREATE NONCLUSTERED INDEX IX_Column4 ON MyTable(Column4)
INCLUDE (Column1, Column2);

执行以下查询时:

SELECT Column1, Column2 FROM MyTable WHERE Column4 LIKE 'Something';

您(很可能)正在使用IX_Column4索引。但在执行类似的事情时:

SELECT Column1, Column2, Column3 FROM MyTable WHERE Column4 LIKE 'Something';

您不会受益于此类指数所提供的优势。

如果您的表格中的行是INSERTED, DELETED or UPDATED,那么您应该检查INDEX FRAGMENTATION and REBUILD or REORGANIZE这些行。

如果您想了解有关索引的更多信息,我会推荐以下文章:

希望它有所帮助。

答案 1 :(得分:1)

对于这种情况,由于您选择了所有列(*),因此将非聚簇索引更改为聚簇索引将增加时间,因为访问其他列(索引中未包含的列,未按顺序排列,也未按顺序排列)来自非聚集索引的INCLUDE)将需要检索具有实际数据的另一页面。

由于您不能按表格拥有多于1个聚簇索引,因此您必须删除现有索引(在这种情况下为PRIMARY KEY)并在之后创建它。

ALTER TABLE dbo.MYTABLE DROP [PK_MYTABLE] -- This might fail if you have foreign keys

ALTER TABLE dbo.MYTABLE ADD CONSTRAINT PK_MYTABLE PRIMARY KEY NONCLUSTERED (ID) 

DROP INDEX [IX_FIELD1] ON [dbo].[MYTABLE]

CREATE CLUSTERED INDEX [IX_FIELD1] ON [dbo].[MYTABLE] (FIELD1)

索引访问时间也可能因其碎片而有很大差异(如果您有许多插入,删除或更新的值不大于或低于上一个/第一个)。

另请注意,如果您正在执行其他操作,如连接,函数调用或其他WHERE过滤器,则引用可能决定不使用索引。