Sql 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中。
嗨 我需要在SQL数据库中记录应用程序中进行的每个步骤的相关信息。 存在某些表,我希望日志应与以下内容相关: 产品-应记录产品创建、更改等的时间。 订单-同上 航运-相同 等等等等等等 需要经常检索数据 我对如何做到这一点没有什么想法:Sql 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中。,sql,sql-server,performance,data-storage,Sql,Sql Server,Performance,Data Storage,嗨 我需要在SQL数据库中记录应用程序中进行的每个步骤的相关信息。 存在某些表,我希望日志应与以下内容相关: 产品-应记录产品创建、更改等的时间。 订单-同上 航运-相同 等等等等等等 需要经常检索数据 我对如何做到这一点没有什么想法: 有一个日志表,它将包含所有这些表的列,然后当我想在UI中表示某个产品的数据时,我会从log中选择*其中LogId=Product.ProductId。 我知道这可能是有趣的有许多科尔,但我有这种感觉,性能将更好。另一方面,此表中将有大量行 对于每种日志类型(Pr
CREATE TABLE [dbo].[Log](
[LogId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NULL,
[Description] [varchar](1024) NOT NULL,
CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED
(
[LogId] 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
ALTER TABLE [dbo].[Log] WITH CHECK ADD CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
[LogId] [int] NOT NULL,
[TableName] [varchar](32) NOT NULL,
[RowId] [int] NOT NULL,
CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED
(
[LogId] ASC,
[TableName] ASC,
[RowId] 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].[LogReference] WITH CHECK ADD CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(
@TableName varchar(32),
@RowId int
)
RETURNS
@Log TABLE
(
LogId int not null,
UserId int not null,
Description varchar(1024) not null
)
AS
BEGIN
INSERT INTO @Log
SELECT [Log].LogId, [Log].UserId, [Log].Description
FROM [Log] INNER JOIN
LogReference ON [Log].LogId = LogReference.LogId
WHERE (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
RETURN
END
GO
要小心预先优化数据库。大多数数据库都相当快,而且有些复杂。您希望首先运行效率测试 第二,将所有内容放在一个表中,使您想要的结果更有可能在缓存中,这将极大地提高性能。不幸的是,这也使得你更可能需要搜索一个巨大的表来找到你想要的东西。这可以通过索引部分地解决,但索引并不是免费的(例如,它们会使编写更昂贵)
我的建议是做一个测试,看看性能是否真的很重要,然后测试不同的场景,看看哪个最快 尝试以一种方式实现数据访问层,以便在需要时可以从一种数据库模型更改为另一种数据库模型-这样,您只需选择一种数据库模型,然后再考虑性能影响 如果不进行性能测试,不准确了解负载的种类,就很难对其进行优化,因为性能取决于许多因素,例如读取次数、写入次数,以及读取和写入是否可能冲突并导致锁定
顺便说一句,我更喜欢选项1——这是最简单的方法,您可以做很多调整来帮助解决可能遇到的各种问题。如果您谈论的是大量数据(数百万行+),那么您将从使用不同的表来存储它们中获益 e、 g.基本示例5000万个日志条目,假设5种不同的“类型”日志表 拥有5 x 1000万行表比拥有1 x 5000万行表更好
- 单个表的插入性能会更好-每个表上的索引会更小,因此作为插入操作的一部分,更新/维护会更快/更容易
- 单个表的读取性能会更好—需要查询的数据更少,需要遍历的索引更小。此外,听起来您需要存储一个额外的列来标识记录是什么类型的日志条目(产品、装运…)
- 在较小的表上维护不那么痛苦(统计、索引碎片整理/重建等)
最近,我听了一位eBay架构师的采访,他强调了在需要性能和可扩展性时分区的重要性,根据我的经验,我非常同意。我肯定会选择选项3,原因有几个: 数据应该在表的字段中,而不是作为表名(选项2)或字段名(选项1)。这样,数据库就更易于使用和维护 桌子越窄,表现越好。行数对性能的影响小于字段数
如果每个表都有一个字段(选项1),当只有少数表受操作影响时,可能会得到很多空字段。我对开发时间有点严格,您认为最推荐的方法是什么?最干净、最有效的方法是列表中的第3位,问题是这是否会太慢。你看,我同意你的看法,问题特别是关于插入和搜索,我不关心检索是否慢。