建议如何扩展和改进执行时代的一个"转基于查询"在一亿排表,增加了一百万的一天
-
05-07-2019 - |
题
我们的公司正在开发一个内部项目,以分析文本文件。这些文本文件是由元数据中提取使用常规expresions.十个计算机24/7的分析文本文件和喂养一个高端的英特尔强SQL服务器2005年数据库所提取的元数据。
简化数据库架构是这样的:
项目 | Id | Name | |----|--------| | 1 | Sample |
Items_Attributes | ItemId | AttributeId | |--------|-------------| | 1 | 1 | | 1 | 2 |
属性 | Id | AttributeTypeId | Value | |----|-----------------|-------| | 1 | 1 | 500mB | | 2 | 2 | 1.0.0 |
AttributeTypes | Id | Name | |----|---------| | 1 | Size | | 2 | Version |
有许多不同的文本的文件类型的不同的元数据内。每个文本的文件,我们有一个 Item
并为每一个元数据提取价值的,我们有一个 Attribute
.
Items_Attributes
让我们避免重复 Attribute
值,它避免了数据库的大小,以增加x^10.
这个特别的架构可以让我们来动态增加新的经常表现形式和获得新的元数据,从新进行处理的文件,无论其内部结构,他们有。
此外,这使我们能够过滤数据和获得动态的报告,根据用户的标准。我们通过过滤的 Attribute
然后枢的结果(http://msdn.microsoft.com/en-us/library/ms177410.aspx).所以这个例子伪sql query
SELECT FROM Items WHERE Size = @A AND Version = @B
将返回的一个枢表这样的
| ItemName | Size | Version |
|----------|-------|---------|
| Sample | 500mB | 1.0.0 |
The application has been running for months and performance decreased terribly at the point is no longer usable. Reports should take no more than 2 seconds and Items_Attributes
表增加了平均10,000,000的行每星期。一切都正确地编入索引和我们花了严重的时间分析和优化查询执行计划。
所以我的问题是,你会如何扩大这个为了减少报告的执行时间?
我们来到这个可能的解决方案:
- 购买更多的硬件和建立一个SQL服务器群集。(我们需要的建议在适当的"聚类"战略)
- 使用的一个关键/价值的数据库,如HBase(我们真的不知道如果将解决我们的问题)
- 使用ODBMS而不是一个RDBMS(我们一直在考虑创建db4o)
- 推动我们的软件云(我们有零的经验)
- 静态生成的报告在运行时间。(我们真的不想)
- 静态索引视为共同报告(绩几乎相同)
- De-正常化的模式(我们的一些报告涉及最多50表在一个单一的查询)
解决方案
也许这份白皮书通过SQL服务器猫队在缺陷的实体属性价值的数据库模型可以帮助: 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)
, ,因为这是不可能建立这样一个指数。
你甚至不能建立一个索引的观点,因为它将包含一个自我加入 attributes
.
可能最好的决定,将以非规范化的表这样的:
id name size version
并创建一个索引 (size, version)
曾有这样的模式的大量的时间。他们从来没有执行。最好的事情就是商店的数据,因为你需要它,在形式:
|ItemName|尺寸|版本| |----------|-------|---------| |样品|500兆|的1.0.0|
然后你不需要的枢轴。并且顺便说一句,请不要打电话给你的原EAV架构"标准化"-这是不正常化。
在我看来就像发行一些OLAP查询的数据库进行了优化只读的交易。不要知道细节,我建议建立一个独立的"数据仓库"优化这样的查询,你在做什么。这将涉及汇总数据(如果可能),非正规化以及还有一个数据基,这是1日的或旧如此。你会逐步更新的数据每天或在任何时间间隔。
请提供确切言和索引,如果你有索引ID列,然后您的查询结果将在扫描
而不是像这样的东西
SELECT FROM Items WHERE Size = @A AND Version = @B
你需要这样做
SELECT FROM Items WHERE ID = 1
换句话说你需要抓住的文本价值观,找到身份证,你是索引,然后使用那作为你的查询返回的结果,而不是
可能也是一个很好的想法,看看在分区功能分发数据
集群做可不能,如果一个节点死(该活动集群),其他节点(被动集群)将成为活跃。...当然也有积极活动的群集,但这是另一个故事
一个短期解决办法可能是使用 水平划分.我假设你最大的表 Items_Attributes
.你可以横向分区这表,把每个分区在一个单独的文件组在一个单独的磁盘控制器。
这是假设你是不是想报告在所有 ItemId
s在一次。
你说50表在一个单一的查询。虽然SQL服务器支持256表在一个单一的、整体的查询,采用这种方法降低了的机会优化生产的一个有效的计划。
如果你坚持的模式,因为它代表,考虑打破你的报告查询下成一系列的步骤,兑现他们的结果成临时(#)表。这种方法可以进行的最具选择性的部分的查询在隔离,而可以,在我的经验,提供性能大的收益。查询一般都比较容易维护。
还(一点,本)你不说哪SQL服务器的版本你在上;但如果你在SQL2005年,鉴于数量表参与在你的报告和该卷的数据,这是值得检查您的SQL服务器进行了修补,至少SP2。
我曾在一个ETL项目使用的表行计数的几百万,其中我们发现,查询的优化在SQL2005题/SP1不能一直生产高效率的查询计划加入超过5表,其中一个或多个表格是这种规模。这个问题得到了解决,在SP2。