我是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的某些字段的事务。如表A中的事务所说的AccountNumber
填充到表B,其中name = accountnumber和value ='[actual帐号]'带有所需的itemID。现在表B非常大,因此使用视图查询特定事务的帐号是永远的。
请注意以前所有这些名称列都在表A中,但由于总是需要更改业务需求以添加更多列,因此团队以这种方式创建结构,以便添加新字段不需要向表A添加新列。 / p>
优化此表的最佳方法是什么。
答案 0 :(得分:1)
您的同事创建的是实体属性值(EAV)商店。不管这些是不是邪恶的东西,我都会放在一边。
简短的回答是:您无法优化查询。
答案越长:您可以在表格B的AV中输入(索引)类型字段,以提高效率。
根据您在其中存储的内容,稍微相关的选项可能是使用触发器在其中维护额外的类型字段,并对后者进行索引。例如,触发器可以维护int
字段,该字段包含标记为int
类型的字段的整数值。
也就是说,不要指望这些解决方案能够带来很好的性能提升,因为你仍然会做很多不必要的连接。请记住,这两个技巧都会增加开销(额外的磁盘空间+与索引维护相关的时间)。
正确的答案是:EAV商店应该只用于存储 meta 信息。
通过meta,我的意思是你很少使用where子句,更不用说非常有选择性了。
换句话说,确定经常查询的关键字段,无论是where子句,join子句,order by子句等。将它们移回表A,并正确索引。
当你在这里时,考虑移动表A中大多数/所有行中存在的东西:由于不再需要表中的name
字段,你移动的每个字段都可以节省空间B,你会得到适当的打字数据作为奖金。