mil*_*n m 4 sql-server sql-server-2012
我有一个 SQL Server 2012 数据库,其中包含大约 2000 个表(每日日志文件),每个表大约有 2000 万条记录。输出select @@Version
Microsoft SQL Server 2012 - Windows NT 6.2 上的 11.0.2100.60 (X64) 标准版(64 位)(内部版本 9200:)
现在,为了生成年度或 3 年报告,我需要对每个表运行查询并“联合所有”结果。查询是动态生成的,通常规模很小。但是在执行“Union all: with 1000 table”之后,它变成了一个巨大的查询。
在处理此类查询时,我收到如下突出显示的错误。
该应用程序已经构建、测试并处于实时生产中,因此我无法使用临时表或哈希表来存储中间结果。
现在,我如何摆脱此错误消息?
查询处理器耗尽了内部资源,无法生成查询计划。这是一种罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。
Dan*_*her 17
错误消息是有原因的。UNION在单个查询中使用数千个表是性能自杀。是的,我知道您的报告应用程序已经投入生产,但我仍然强烈建议您返回开发团队并更新应用程序,或者更好的是,改为在存储过程中重建其逻辑。
正如您在问题中建议的那样,创建一个临时表,按顺序运行每个查询并将结果转储到临时表中。然后,从临时表编译报告。所有这些都可以在存储过程中完成,存储过程还将涵盖其他重要方面,如安全性和性能。
这具有一系列优点:
我不是想惹你。我坚信,如果你现在不重建报告,你很可能有一天不得不继续前进。
小智 5
为了支持 Daniel Hutmacher 的完美回答,我敢打赌,如果您致电 Microsoft,他们会告诉您错误消息的内容。也许几年后,您会了解到 SQL Server 2019 支持 16,000 个表连接。
我什至不会创建临时表。我会创建一个普通的表,Megalog,填充它,并创建一个日常进程来在它被剪切时附加每天的日志。我将所有查询都基于 Megalog,并在删除关联的日志表时删除过时的行。我知道您现在受到限制,因此无法实现,但 IMO 您别无选择。您不妨拥有一张桌子来支持您的业务。
从设计的角度来看,您的错误是经典设计错误的一个很好的例子:将数据放入元数据中。元数据中的数据是 1 天日志表的存在,其数量无限制地增长。当模式无限制地增长时,它持有一些应该在行中的东西, a/k/a data。
当需要修改设计时——鉴于您的问题,它似乎很快就会发生——我建议您寻找动态修改架构的情况,并寻找使用静态架构的机会。系统和您的 SQL 将变得更简单、更稳定。
肯定有人会告诉你,查询一个 2000 万行的表比查询一个 2000 亿行的表要快。在某种程度上,这是真的。但如果它是按日期聚类的,则较小的表平均仅避免 log2(2000) = ~10 次查找操作,主要针对缓存。如果您愿意做这项工作并接受复杂性,SQL Server 具有分区功能,可以使该数字过时。为此目的而编入索引的单个表的性能应该比您目前正在处理的 orangoutang 好得多。;-)
| 归档时间: |
|
| 查看次数: |
17641 次 |
| 最近记录: |