繁体   English   中英

在具有2亿行的SQL表上的性能查询?

[英]Performance Queries on a SQL table that has 200 million rows in it?

我有一个表,其中有2亿行,并且每天都会增加150万行。

我需要查询它来获取一段时间的数据,比如说3个月的数据,这至少要花半个小时的时间来检索它。

是否有任何方法可以对表或查询进行微调以在不到一分钟或两分钟的时间内执行并更快地获取数据。

CREATE TABLE [dbo].[Chnl](
    [Id] int IDENTITY(1,1) NOT NULL 
        CONSTRAINT [PK_Chnl] PRIMARY KEY CLUSTERED
    ,[ChnlNo] int NOT NULL
    ,[ChnlName] varchar(50) NULL
    ,[Active] bit NULL
)

CREATE TABLE [dbo].[ChnlData]( 
    [Id] [int] IDENTITY(1,1) NOT NULL
        CONSTRAINT [PK_ChnlData] PRIMARY KEY CLUSTERED
    ,[ChnlId] [int] NOT NULL
    ,[ChnlValue] [decimal](6, 2) NOT NULL
    ,[ChnlDataLogTime] [datetime] NOT NULL
    ,[Comments] [varchar](max) NULL
    ,[Active] [bit] NULL
    ,CONSTRAINT [FK_ChannelData_Channel] FOREIGN KEY([ChnlId]) REFERENCES [dbo].[Chnl] ([Id]) 
)

它只是一个简单的查询:

SELECT * 
FROM [ChnlData]
WHERE  ChnlId in (519, 520)

它获取了700万条记录,并且花费了9分钟来获得该记录。 现在,数据库大小为32 GB

对表进行分区(基于年或月)将是可能的解决方案之一。 您可能必须为动态分区创建脚本。

除了先前的方法之外,您还可以实现DataWarehousing风格的解决方案。 就像您可以为每个记录创建一个代理键(唯一键-可能是一个序列),并准备一个类似结构的查找表。

例如:密钥1234M-1235M密钥集将位于XX分区中。

这可能不容易实现。 但这是一个干净的解决方案。

对于OLTP环境,仅分区表会有很大帮助。

为该数据分配一个单独的数据库。 并使用并行查询(包含多个节点处理器),可以加快查询输出。

首先,我将创建一个索引来覆盖您的搜索参数,至少应覆盖包含您的日期的列。 如果这还不够的话,您可能需要考虑Maheswaran的建议,并使用分区和文件组,这对索引特别有效,因为它们可以分别覆盖每个分区。

但总的来说,这很难说,因为您的问题过于广泛。 从表中获取多少列和哪些类型的数据,表中的列总数为多少? WHERE子句中的过滤器是什么(您的索引将使用这些过滤器)。 您的3个月批处理中将包含多少数据大小(可以在每3个月的时间段内创建文件组,这样就可以更轻松地针对这些数据进行归档和使用批量操作)。 等等。

现在有太多的猜测工作需要完成。

编辑:由于数字更改为远远小于您原来的数字,因此一个简单的索引现在就足够了。 尝试这个:

CREATE NONCLUSTERED INDEX CHLNDATA_QUARTER_IDX ON ChnlData (ChnlId, ChnlDataLogTime)

然后,例如,如果您想要过去三个月的数据,则可以这样获得:

SELECT * 
FROM [ChnlData]
WHERE  ChnlId in (519, 520)
AND YEAR(ChnlDataLogTime) IN (YEAR(DATEADD(MONTH, -3, GETDATE())), YEAR(GETDATE()))
AND MONTH(ChnlDataLogTime) BETWEEN MONTH(DATEADD(MONTH, -3, GETDATE())) AND MONTH(GETDATE())

没有检查语法,但是应该正确或足够接近。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM