我今天在我的应用程序中询问了以下有关数据库设计和性能问题的问题。
但是,不能得到太多的答复。我不知道,我可能没有正确解释这个问题。现在,我重新定义了我的问题,希望得到专家的一些建议。
从特定表中选择数据时,我遇到了性能问题。该应用程序的业务逻辑如下:我有许多导入过程,这些过程导致在其父列名称下创建数据透视列,同时将它们显示给用户。随着列的旋转,系统需要时间将行转换为列,这会导致性能下降。与此功能相关的数据库表如下: 可以有 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'