2013-04-25 33 views
2

我对SQL Server相当陌生,我对这个以非常尴尬的方式实现的非常大的表存在此问题。这是什么样的设计看起来像在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中的交易填充到具有name = accountnumber和value ='[实际帐户号]'的表B'具有所需的i temID。现在表B非常大,因此使用视图查询特定事务的帐号是永久的。

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

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

+0

请添加更多详细信息,这对帮助处理这些信息非常困难 - 特别是对于优化。例如。我没有看到“accountnumber”和“transaction”字段或它们的值是什么字段,我不明白为什么要在表B中查找“实际帐号” - 从您发布的信息看来,它似乎是一个简单的“insert '命令... – 2013-04-25 08:05:23

+0

@mark表A有一些事务的数据,为什么剩余的字段被插入到表B中,现在表b现在非常大,并且基于已经插入到表B中的其他字段进行永久搜索。它就像把表格分成2个,其中一些字段的名称值插入表B – kolexinfos 2013-04-25 08:22:40

+1

我看到了。在这种情况下:保持此模型不可能实现“高质量优化”。你需要做的是重新设计数据库(这将是唯一的优秀解决方案)或者用于快速和肮脏的“出来”:)在tableB中引入一个新的关键字段,它是在EAV表中定义的ID,告诉[名称]字段的“类型”。所以EAV就像“AccountNumber = 1,Transaction = 2等”。这样,您可以在开始在TableB中搜索之前筛选出大量记录 – 2013-04-25 08:34:27

回答

1

您的同事创建的是实体属性值(EAV)存储。我会留下这些是否是邪恶的东西。

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

较长的答案是:您可能能够在AV中的(索引)类型字段中折腾您的表B,以使效率更高一些。

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

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

正确的答案是:一个EAV商店应该只能用于存储meta信息。

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

换句话说,确定经常查询的关键字段,是否用于where子句,连接子句,子句排序等。将它们移回到表A中,并将它们正确编入索引。

当你在它的时候,考虑移动表A中大部分/所有行中的东西:你移动的每个字段将节省你的空间,因为不再需要表B中的name字段,并且你会得到适当的类型数据作为奖励。