2016-12-01 56 views
2

我在我的数据库表中包含500万条记录:优化性能 - 索引

CREATE TABLE [dbo].[PurchaseFact](
    [Branch] [int] NOT NULL, 
    [ProdAnal] [varchar](30) NULL, 
    [Account] [varchar](12) NULL, 
    [Partno] [varchar](24) NULL, 
    [DteGRN] [date] NULL, 
    [DteAct] [date] NULL, 
    [DteExpect] [date] NULL, 
    [OrderNo] [bigint] NULL, 
    [GRNNO] [varchar](75) NULL, 
    [SuppAdv] [varchar](75) NULL, 
    [Supplier] [varchar](12) NULL, 
    [OrdType] [varchar](4) NULL, 
    [UnitStock] [varchar](4) NULL, 
    [OrderQty] [float] NULL, 
    [RecdQty] [float] NULL, 
    [Batch] [varchar](100) NULL, 
    [CostPr] [float] NULL, 
    [Reason] [varchar](2) NULL, 
    [TotalCost] [float] NULL, 
    [Magic] [bigint] IDENTITY(1,1) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [Magic] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

正如你可以从上面看到的 - 一个CLUSTERED INDEX正在对MAGIC列使用这是一个UNIQUE栏。

数据检索时间为以下SELECT statement是远远超过,这导致生成的问题8分钟:

SELECT Branch, 
    Supplier, 
    ProdAnal, 
    DteGRN AS Date, 
    PartNo AS Partno, 
    OrderNo, 
    OrderQty, 
    TotalCost, 
    CostPr 
FROM dbo.PurchaseFact src 
WHERE YEAR(DteGRN) = 2016 

剔除WHERE clause也不会使查询跑得更快。 我都试过了,与CLUSTERED index一起包括在希望它会运行得更快,但无济于事一个UNIQUE index

CREATE UNIQUE INDEX Unique_Index ON dbo.PurchaseFact ([Branch], [Supplier], [Magic]) 
INCLUDE ([ProdAnal], [Account], [Partno], [DteAct], [DteExpect], [OrderNo], [GRNNO], 
[SuppAdv], [OrdType], [UnitStock]) 

有什么办法,我可以在这个表上优化性能的时间,或者我应该诉诸归档旧数据?

任何意见将不胜感激。

+0

2016年返回多少行?数据传输可能需要一些时间。 – jarlh

+1

你可以添加一个持续计算的列来做那年的计算吗?然后,您可以在此字段中添加非聚集索引并包含其他字段。 –

+0

@jarlh - 返回的1,600万条记录。 – PKirby

回答

4

这是您的where条款:

WHERE YEAR(DteGRN) = 2016 

如果表中有500万行,那么这将返回大量的数据,假设日期的任何合理分布。数据量可能负责查询的时间长度。

一两件事你可以做的是修改WHERE,然后把索引相应的列:

WHERE DteGRN >= '2016-01-01' and DteGRN < '2017-01-01' 

这可以再取上PurchaseFact(DteGRN)指数的优势。但是,考虑到可能返回的行数,索引可能不会有太大的帮助。

更大的问题是,为什么您的报告申请2016年带回的所有行,而不是总结他们的数据库中。我怀疑你的报告应用程序存在体系结构问题。

+1

谢谢戈登 - 这当然有助于加快速度。从8:44分钟降至2:50分钟。 – PKirby

0

对不起,无法添加评论。

为了进一步提高性能(如果你可以用UPDATE生活开销),创建包括只在查询的SELECT部分​​中的列覆盖索引。

0

对不起格式 - 我做它在移动:

试试这个:

创建非聚集索引IX_YourName ON dbo.PruchaseFact(DateGRN)包括:(所有的选择,但不排序列) ;

,并避免在WHERE语句中使用任何功能。当您使用该引擎时,引擎会读取ENTIRE列以在每一行上应用该功能。使用(如上所述)至少让引擎为你的范围创建适当的索引统计数据和桶(比如在这种情况下一年的值)。