0

我今天在我的应用程序中询问了以下有关数据库设计和性能问题的问题。

从一个沉重的表中进行数据库设计和数据检索

但是,不能得到太多的答复。我不知道,我可能没有正确解释这个问题。现在,我重新定义了我的问题,希望得到专家的一些建议。

从特定表中选择数据时,我遇到了性能问题。该应用程序的业务逻辑如下:我有许多导入过程,这些过程导致在其父列名称下创建数据透视列,同时将它们显示给用户。随着列的旋转,系统需要时间将行转换为列,这会导致性能下降。与此功能相关的数据库表如下: 可以有 N 个客户端。CLT_Clients 表存储客户信息。

一个客户可以有 N 个项目。PRJ_Projects 表存储项目信息和到客户端的链接。

一个项目可以有 N 个列表。PRJ_Listings 表存储列表信息和项目链接。

可以有 N 个与列表相关联的源实体。ST_Entities 表存储源实体信息和列表的链接。

此源实体是包含 InvestorID、头寸值、源日期、活动和公式状态的实际导入。

The name of the import e.g. L1Entity1 is stored in ST_Entities table alongwith ID field i.e. EntityID
InvestorID, Position, Source Date, Active and Formula values get stored in ST_Positions table 

数据库图 数据库设计

数据需要查看如下: 数据视图

通过这种设计,我可以处理 N 次导入,因为 Position、Source Date、IsActive、Formula 列会被透视。

我在此设计中面临的问题是,当系统必须为超过 10-12 个源实体选择数据时,系统执行速度非常慢,并且要求显示大约 150 个源实体。因为数据不是按行存储的,我需要按列显示,因此编写动态查询来旋转这些需要很长时间的列。

问题 1:请评论/建议我当前的数据库设计是否正确或需要使用新设计进行更改,方法是分别为 Position、Source Date、IsActive、Formula 取 150 列;以这种新方式,数据已经以我需要检索的方式存储,即我不必旋转/取消旋转它。但缺点是:

a) 此表中的列数将超过 600 列?

b) 源实体将有限制,即 150 个。

问题 2:如果我需要坚持目前的状态,可以做些什么来提高性能?

请参阅下面的索引和 Pivot 方法信息:

关于 Position 表中的索引,我还采用了带有聚集索引的 ProjectID 字段,因为数据是根据 ProjectID 或 EntityID 从 Position 表中选择的。

每当 EntityID 用于从 Position 表中选择数据时,它总是在 JOIN 中使用。并且每当 ProjectID 用于从该表中选择数据时,它总是在 WHERE 中使用。

这里要注意的是,我在 ProjectID 上有一个聚集索引,但我没有在 Pivoted 列或 EntityID 上获取任何索引。这里有改进的余地吗?

使用的旋转方法:

Example 1:

'Select * From
(
    Select DD.InvestorID,Cast(1 As Bit) As IsDSInvestor,DD.Position,
    Case DD.ProjectID
    When ' + CAST(@ProjectID AS VARCHAR) +' Then DE.SourceName 
    Else ''' + @PPDeliveryDate + '''+DE.SourceName
    End As SourceName
    From DE_PositionData DD
    Inner Join DE_DataEntities DE ON DE.EntityID=DD.EntityID
    Where DD.ProjectID IN (' + CAST(@ProjectID AS VARCHAR) +',' + CAST(@PreviousProjectID AS VARCHAR) +') AND InvestorID IS NOT NULL

) IDD
Pivot
(
    max(Position) for SourceName in ('+ @DataColumns+')
) as p1'

示例 2:

'Select * From
    (
        Select DD.InvestorID As DSSOFID,Cast(1 As Bit) As IsActiveInvestor,
        Case ST.SourceTypeCode
            When ''RSH'' Then Cast(IsNull(DD.IsActive,0) As Int)
            Else Cast(IsNull(DD.IsActive,1) As Int) 
        End As IsActive,
        ''~''+DE.SourceName As ActiveSourceName
        From DE_DataEntities DE
        Left Join DE_PositionData DD ON DE.EntityID=DD.EntityID
        Left Join 
        (
            Select * From #DataSources
            Where ProjectID=' + CAST(@ProjectID AS VARCHAR) +'
        ) ST ON ST.ESourceID=DE.ESourceID
        Where DE.ProjectID=' + CAST(@ProjectID AS VARCHAR) +' AND ST.SourceTypeCode NOT IN (''PBC'',''EBL'',''REG'')
        AND InvestorID IS NOT NULL

    ) IDD
    Pivot
    (
        Max(IsActive) for ActiveSourceName in ('+ @DataColumns+')
    ) As p1'
4

1 回答 1

2

我建议以下。

您应该以标准化格式存储数据。您应该能够设置索引以使数据的旋转更快。如果您发布用于透视的实际查询,我们可能会提供帮助。

您希望以这种方式存储数据的原因有很多:

  • 重复块数量的灵活性
  • 许多数据库对表格的列数或总宽度有限制。您不希望您的设计接近这些限制。
  • 您可能需要有关每个块的附加信息。我总是在我的表中包含 CreatedBy 和 CreatedAt 列,你会希望每个块都有这个。
  • 您在摘要方面具有额外的灵活性。
  • 添加/删除中间值很麻烦。

也就是说,透视表有一个关键优势:它是用户想要看到的。如果您的数据每天只更新一次,那么您应该使用数据透视表创建一个报表。

如果您的数据在一天中以增量方式更新,那么您可以设置触发器(或存储过程代码)来更新基表和报告摘要。

但正如我之前所说,您应该问另一个问题是您用于旋转的特定方法。也许我们可以提高那里的性能。

于 2012-06-01T23:22:56.177 回答