【发布时间】:2013-01-15 09:25:01
【问题描述】:
目前我面临查询和性能问题 存储过程。以下是场景:
我们在一个数据库 (SQL Server 2000 SP4) 中有 3-4 个表
有大量的记录。其中一张表超过2500万
记录。这些表保存着销售记录和成千上万的
每天添加到其中的记录。每当执行存储过程时,它需要
15-30分钟完成。表上有 3-4 个连接。用户是
经常抱怨它。索引是正确的。为了提高性能
我们已经实现了分区视图。该解决方案由
引用以下article on MSDN
我们按年度和业绩划分了销售记录
已改进,查询/存储过程现在需要 3-5 分钟才能运行。改善
进一步,我们按月划分销售记录。我们在维护
4 年的数据,现在我们接近 48 个销售数据表(之后
按月拆分销售数据)。我期待这可以提高性能。但
这没有发生。查询的执行速度比前一个慢得多
(数据的年度拆分)这让我感到惊讶。也看过之后
查询计划我发现它正在对所有 48 个销售表进行索引扫描
只扫描相关表。例如。当被查询存储过程时
期间19-NOV-2012和20-DEC-2012,应该只考虑2个表NOV-2012
和DEC-2012。但它正在考虑所有 48 张桌子。所以我的问题是:
为什么要考虑所有表而不是只考虑 相关表格。例如。在上面的例子中
NOV-2012和DEC-2012为什么年度逻辑(按年份拆分销售记录)是 表现优于按月逻辑(按月拆分销售记录)
以下是分区视图的代码。
例如年份 其他年份省略。
SELECT * FROM tbl_Sales_Jan2010
UNION ALL
SELECT * FROM tbl_Sales_Feb2010
UNION ALL
SELECT * FROM tbl_Sales_Mar2010
UNION ALL
SELECT * FROM tbl_Sales_Apr2010
UNION ALL
SELECT * FROM tbl_Sales_May2010
UNION ALL
SELECT * FROM tbl_Sales_Jun2010
UNION ALL
SELECT * FROM tbl_Sales_Jul2010
UNION ALL
SELECT * FROM tbl_Sales_Aug2010
UNION ALL
SELECT * FROM tbl_Sales_Sep2010
UNION ALL
SELECT * FROM tbl_Sales_Oct2010
UNION ALL
SELECT * FROM tbl_Sales_Nov2010
UNION ALL
SELECT * FROM tbl_Sales_Dec2010
以下是表结构。
CREATE TABLE [dbo].[tbl_Sales_Jan2010](
[SalesID] [numeric](10, 0) NOT NULL,
[StoreNumber] [char](3) NOT NULL,
[SomeColumn1] [varchar](15) NOT NULL,
[Quantity] [int] NOT NULL,
[SalePrice] [numeric](18, 2) NOT NULL,
[SaleDate] [datetime] NOT NULL,
[DeptID] [int] NOT NULL,
[CatCode] [char](3) NOT NULL,
[AuditDate] [datetime] NOT NULL CONSTRAINT [DF_tbl_Sales_Jan2010_EditDate] DEFAULT (getdate()),
[SomeColumn2] [varchar](15) NULL,
[SaleMonthYear] [int] NULL CONSTRAINT [DF__tbl_Sales__SaleY__Jan2010] DEFAULT (12010),
[SaleDateInIntFormat] [int] NULL,
CONSTRAINT [PK_tbl_Sales_Jan2010] PRIMARY KEY CLUSTERED
(
[SalesID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[tbl_Sales_Jan2010] WITH CHECK ADD CHECK (([SaleMonthYear] = 12010))
下面是查询
SELECT SUM(C.Quantity) as total
FROM Productdatabase.dbo.tbl_Product A , Productdatabase.dbo.tbl_Product_Category B, XDatabase.dbo.vw_Sales_Test C, tbl_Store D
WHERE A.ProductID = B.ProductID AND B.CategoryID = @CateID
AND C.SomeColumn = A.PRoductCode
AND D.StoreCode = C.StoreNumber
AND D.country = @country
AND D.status = 0
And C.SaleMonthYear between @BeginMonthYear and @EndMonthYear
AND C.SalDate between @FromSaleDate and @ToSaleDate
【问题讨论】:
-
表设计、分区视图详细信息、索引详细信息和实际查询真的很有帮助
-
2500 万可能比你习惯的要多,但也不是巨大。
-
我想看看查询计划。我看不出分区消除在这里不起作用的原因。但是,您已经交换了月份和年份,这可能会让您相信它不起作用......
标签: sql sql-server