我的桌子有2亿行,每天会增加150万。
我需要查询它以获取一段时间的数据,例如3个月的数据,这需要至少半小时的时间来检索它。
是否有任何方法可以在不到一分钟或2分钟内对表或查询进行微调,以便更快地获取数据。
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千兆字节
答案 0 :(得分:0)
对表格进行分区(基于年份或月份)将是可能的解决方案之一。您可能必须为动态分区创建脚本。
除了之前的方法,您还可以实施DataWarehousing风格的解决方案。 就像你可以为evry记录创建一个代理键(唯一键 - 可能是一个序列),并准备一个像结构一样的查找表。
Ex:Keys 1234M - 1235M键组将位于XX Partition .. etc。
这可能不容易实现。但这是一个干净的解决方案。
对于OLTP环境,patition表只会有很多帮助。
为tis数据分配单独的数据库。使用并行查询(使用多个节点处理器),我们可以加快查询输出。
答案 1 :(得分:0)
首先,我会创建一个索引来覆盖您的搜索参数,至少这应该涵盖包含您的日期的列。如果这还不够,您可能需要查看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())
没有检查语法,但应该正确或足够接近。