Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中。_Sql_Sql Server_Performance_Data Storage - Fatal编程技术网

Sql 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中。

Sql 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中 性能考虑:将行分散在多个表中,而不是将所有行集中在一个表中。,sql,sql-server,performance,data-storage,Sql,Sql Server,Performance,Data Storage,嗨 我需要在SQL数据库中记录应用程序中进行的每个步骤的相关信息。 存在某些表,我希望日志应与以下内容相关: 产品-应记录产品创建、更改等的时间。 订单-同上 航运-相同 等等等等等等 需要经常检索数据 我对如何做到这一点没有什么想法: 有一个日志表,它将包含所有这些表的列,然后当我想在UI中表示某个产品的数据时,我会从log中选择*其中LogId=Product.ProductId。 我知道这可能是有趣的有许多科尔,但我有这种感觉,性能将更好。另一方面,此表中将有大量行 对于每种日志类型(Pr

我需要在SQL数据库中记录应用程序中进行的每个步骤的相关信息。 存在某些表,我希望日志应与以下内容相关: 产品-应记录产品创建、更改等的时间。 订单-同上 航运-相同 等等等等等等

需要经常检索数据

我对如何做到这一点没有什么想法:

  • 有一个日志表,它将包含所有这些表的列,然后当我想在UI中表示某个产品的数据时,我会从log中选择*其中LogId=Product.ProductId。 我知道这可能是有趣的有许多科尔,但我有这种感觉,性能将更好。另一方面,此表中将有大量行
  • 对于每种日志类型(ProductLogs、OrderLogs等)都有许多日志表。我真的不喜欢这种想法,因为它不一致,而且有许多具有相同结构的表是没有意义的,但是(?)在具有较少行数的表中搜索时可能会更快(m I错了?)
  • 根据第1条语句,我可以做第二个多对一表,该表将包含LogId、TableNameId和RowId cols,并将日志行引用到数据库中的许多表行,而不是使用UDF来检索数据(例如,日志id 234属于CustomerId 345处的表Customer,属于productId=RowId的产品表);我认为这是最好的方法,但同样,可能会有大量的行,这会减慢搜索速度吗?或者应该这样做,你说呢
  • 上述列表中的3号示例:

    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万行表更好

    • 单个表的插入性能会更好-每个表上的索引会更小,因此作为插入操作的一部分,更新/维护会更快/更容易

    • 单个表的读取性能会更好—需要查询的数据更少,需要遍历的索引更小。此外,听起来您需要存储一个额外的列来标识记录是什么类型的日志条目(产品、装运…)

    • 在较小的表上维护不那么痛苦(统计、索引碎片整理/重建等)
    本质上,这是关于数据分区的。从SQL 2005开始,它内置了对分区的支持(请参阅),但您需要Enterprise Edition,它基本上允许您在一个表中对数据进行分区以提高性能(例如,您将拥有一个日志表,然后定义如何对其中的数据进行分区)


    最近,我听了一位eBay架构师的采访,他强调了在需要性能和可扩展性时分区的重要性,根据我的经验,我非常同意。我肯定会选择选项3,原因有几个:

    数据应该在表的字段中,而不是作为表名(选项2)或字段名(选项1)。这样,数据库就更易于使用和维护

    桌子越窄,表现越好。行数对性能的影响小于字段数


    如果每个表都有一个字段(选项1),当只有少数表受操作影响时,可能会得到很多空字段。

    我对开发时间有点严格,您认为最推荐的方法是什么?最干净、最有效的方法是列表中的第3位,问题是这是否会太慢。你看,我同意你的看法,问题特别是关于插入和搜索,我不关心检索是否慢。