我们公司正在开发一个内部项目来解析文本文件。这些文本文件由使用常规表达式提取的元数据组成。十台计算机24/7解析文本文件……
很多时候都使用这样的模式。他们从来没有表现好。 最好的方法是根据需要存储数据,格式如下:
| ItemName |尺寸|版本| | ---------- | ------- | --------- | |样品| 500mB | 1.0.0 |
然后你不需要转动。顺便说一下,请不要将原来的EAV架构称为“规范化” - 它没有规范化。
您在一个查询中提到了50个表。虽然SQL Server在单个查询中支持多达256个表,但采用这种方法可以降低优化器生成有效计划的几率。
如果您坚持使用现有架构,请考虑将报告查询分解为一系列步骤,这些步骤将其结果实现为临时(#)表。 这种方法使您能够独立地执行查询中最具选择性的部分,并且根据我的经验,可以提供巨大的性能提升。查询通常也更易于维护。
另外(有点远景,这个)你没有说你在哪个SQL服务器版本;但是如果您使用的是SQL 2005,考虑到报告中涉及的表的数量和数据量,值得检查您的SQL服务器是否已修补到至少SP2。
我使用具有数亿行行数的表来处理ETL项目,我们发现SQL 2005 RTM / SP1中的查询优化器无法始终为加入超过5个表的查询生成有效计划,其中一个或多个表是这个规模。此问题已在SP2中解决。
在我看来,就像在针对OLTP事务优化的数据库上发布一些OLAP查询一样。不知道细节,我建议建立一个单独的“数据仓库”,针对您正在进行的查询进行优化。这将涉及聚合数据(如果可能),非规范化以及还具有1天左右的数据库。您可以每天或以您希望的任何间隔逐步更新数据。
也许这篇由SQL Server CAT团队撰写的关于Entity-Attribute-Value数据库模型陷阱的白皮书可以帮助: http://sqlcat.com/whitepapers/archive/2008/09/03/best-practices-for-semantic-data-modeling-for-performance-and-scalability.aspx
我将从发布确切的表元数据(以及索引详细信息),确切的查询文本和执行计划开始。
使用当前表格布局,查询类似于:
SELECT FROM Items WHERE Size = @A AND Version = @B
无法使用复合索引 (Size, Version) 因为建立这样的索引是不可能的。
(Size, Version)
您甚至无法构建索引视图,因为它将包含自联接 attributes 。
attributes
可能最好的决定是像这样对表进行非规范化:
id name size version
并创建一个索引 (size, version)
(size, version)
请发布准确的DDL和索引,如果您在ID列上有索引,那么您的查询将导致扫描
而不是像这样的东西
你需要这样做
SELECT FROM Items WHERE ID = 1
换句话说,您需要获取文本值,找到要编入索引的ID,然后将其用作查询以返回结果
查看分区功能以分发数据可能也是一个好主意
集群是为了可用性而不是性能,如果一个节点死亡(活动集群),另一个节点(被动集群)将变为活动状态....当然还有活动的主动集群但这是另一个故事
短期修复可能是使用 水平分区 。我假设你最大的桌子是 Items_Attributes 。您可以对此表进行水平分区,将每个分区放在单独的磁盘控制器上的单独文件组中。
Items_Attributes
假设您没有尝试报告所有内容 ItemId 一下子。
ItemId