2

我对 SQL Server 还很陌生,我在这个非常大的表上遇到了这个问题,这个表是以一种相当尴尬的方式实现的。这是设计外观的摘要图片

表 A

itemID uniqueidentifier PK
name   vchar(32)
datecreated datetime
dateprocessed datetime
datereviewed datetime
approvalstatus int
workflowstatus int

表 B

fieldID uniqueidentifier PK
itemID  uniqueidentifier FK(referencing table A's itemID)
name    vchar(32)
value   vchar(32)

在表 A 中,我们记录了一些交易记录,其中一些字段被填充到表 B。例如AccountNumber,表 A 中的交易被填充到表 B 中,名称 = accountnumber 和 value = '[actual account number]' 以及所需的 itemID . 现在表 B 非常大,因此使用视图查询特定交易的帐号需要很长时间。

请注意,所有这些名称列以前都在表 A 中,但由于不断变化的业务需要添加更多列,导致团队以这种方式创建结构,以便添加新字段不需要向表 A 添加新列。

优化此表的最佳方法是什么。

4

1 回答 1

1

您的同事创建的是实体属性值 (EAV) 存储。不管这些是不是邪恶的东西,我都会放在一边。

简短的回答是:您无法优化查询。

更长的答案是:您也许可以在表 B 的 AV 中添加一个(索引)类型字段,以使事情变得更高效。

根据您在其中存储的内容,一个稍微相关的选项可能是使用触发器在其中维护额外的类型化字段,并为后者编制索引。例如,触发器可以维护一个int字段,该字段保存标记为类型为的字段的整数值int

也就是说,不要指望这些解决方案会大大提高性能,因为您仍然会进行大量不必要的连接。请记住,这两个技巧都会增加开销(额外的磁盘空间 + 与索引维护相关的时间)。

正确答案是:EAV 存储应该只用于存储信息。

所谓元,我的意思是你很少使用 where 子句的东西,更不用说一个非常有选择性的东西了。

换句话说,确定经常查询的关键字段,无论是where子句,join子句,order by子句等。将它们移回表A,并正确索引它们。

当您使用它时,请考虑从表 A 中移动大多数/所有行中存在的内容:由于不再需要name表 B 中的该字段,您移动的每个字段都会为您节省空间,并且您会得到适当的输入数据作为奖励。

于 2013-04-25T08:22:35.090 回答