需要提高性能查询具有数百万行的表 - SQL Server

时间:2017-05-03 13:56:14

标签: java sql-server jdbc hikaricp

一旦在性能测试(读取和插入)中负载增加,审计跟踪表上的此查询开始变慢,并且我已经完成了索引编制。使用此查询以及这些表和索引,我还能做些什么?

CREATE TABLE [dbo].[mod2] (
  [id] [int] IDENTITY,
  [userId] [int] NOT NULL,
  [epochTime] [bigint] NOT NULL,
  [forecastId] [int] NOT NULL,
  [description] [char](12) NOT NULL,
  [auxText] [text] NULL,
  [auxDate] [date] NULL
);


ALTER TABLE [dbo].[mod2] ADD CONSTRAINT PK_mod2 PRIMARY KEY(ID);

ALTER TABLE [dbo].[mod2]  WITH CHECK
    ADD CONSTRAINT [FK_mod2_forecastId] FOREIGN KEY([forecastId])
    REFERENCES [dbo].[forecast] ([id]);

ALTER TABLE [dbo].[mod2] CHECK CONSTRAINT [FK_mod2_forecastId];

ALTER TABLE [dbo].[mod2]  WITH CHECK
    ADD CONSTRAINT [FK_mod2_userId] FOREIGN KEY([userId])
    REFERENCES [dbo].[user] ([id]);

ALTER TABLE [dbo].[mod2] CHECK CONSTRAINT [FK_mod2_userId];

CREATE NONCLUSTERED INDEX IX_modification_auxDate ON [dbo].[mod2] (auxDate ASC);

CREATE NONCLUSTERED INDEX IX_modification_epochTime ON [dbo].[mod2] (epochTime ASC);

CREATE NONCLUSTERED INDEX IX_modification_description ON [dbo].[mod2] (description ASC);

CREATE NONCLUSTERED INDEX IX_modification_forecastId ON [dbo].[mod2] (forecastId ASC);

CREATE NONCLUSTERED INDEX IX_modification_userId ON [dbo].[mod2] (userId ASC);

这是我的疑问:

SELECT name, epochTime, auxDate 
    FROM mod2 WITH (NOLOCK)
    JOIN [user] ON [user].id = mod2.userId 
    WHERE forecastId = ? AND description = ? AND auxDate = ?

这是一个遗留系统,在我将这些索引放在其上并将description字段从VARCHAR更改为CHAR

之前,它正在抓取

预测和用户id字段为INT,并且索引类似。

2 个答案:

答案 0 :(得分:2)

你可以在这里做一些事情。

一个是确保user字段id上有一个聚集索引(可能存在,但确保不会受到伤害)。

您输入的各个索引并不是很好 - 特别是考虑到您显示的查询模式 - 将使用它们中的任何一个(因为它们不包含完整数据),或者其中一些可能会被使用,然后将提供完整的表格,以便选出完成查询所需的剩余数据。

对于此特定查询,对于mod2,我可能会在userId上添加一个索引covering forecastIddescription和{ {1}} - 这样索引包含完成查询所需的所有数据(在auxDate侧)。

答案 1 :(得分:0)

CREATE NONCLUSTERED INDEX IXmod2_user_desc_forecast_auxdate 
ON [dbo].[mod2] (userId, forecastId, description, auxDate DESC);

,查询计划如下所示:

  |--Nested Loops(Inner Join, OUTER REFERENCES:([MyDB].[dbo].[mod2].[id]) OPTIMIZED)
       |--Nested Loops(Inner Join, OUTER REFERENCES:([MyDB].[dbo].[user].[id], [Expr1006]) WITH UNORDERED PREFETCH)
       |    |--Clustered Index Scan(OBJECT:([MyDB].[dbo].[user].  [PK_user]), ORDERED FORWARD)
       |    |--Index Seek(OBJECT:([MyDB].[dbo].[mod2].[IX_mod2_user_desc_forecast_auxdate]), SEEK:([MyDB].[dbo].[mod2].[userId]=[MyDB].[dbo].[user].[id] AND [MyDB].[dbo].[mod2].[forecastId]=(40357) AND [MyDB].[dbo].[mod2].[description]='SAVE' AND [MyDB].[dbo].[mod2].[auxDate]='2017-01-31') ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([MyDB].[dbo].[mod2].[PK_mod2]), SEEK:([MyDB].[dbo].[mod2].[id]=[MyDB].[dbo].[mod2].[id]) LOOKUP ORDERED FORWARD)