【发布时间】:2011-10-22 16:01:41
【问题描述】:
此问题适用于用 SQL-92 编写的存储过程
即 Oracle PL/SQL、SQL Server T-SQL 或 DB2 SQL
我正在维护一个 11000 行的存储过程。
我发现在存储过程结束时我需要报告 80 列数据。
这个存储过程有 3 个不同的阶段。
- 数据收集(将数据从活动表复制到存储过程中间表)
我需要进行数据收集以保持一致性,因为在存储过程执行到第 10,000 行时,第 30 行的实时数据(即在成员表中)可能已经发生了变化
提交状态原子性在此处保持(在复制所需的所有数据之前不提交) - 计算(大量 SQL,足够复杂以至于游标或视图无法完成工作)
- 写回永久表(发票、AR、付款)
提交状态原子性在此处保持(在复制所需的所有数据之前不提交)
“中间”表仅用于存储过程。
它们被索引用于连接下线但没有
PK/FK 参照完整性约束或唯一索引
因为这些会大大减慢执行速度
指向实时数据(不断变化)
当您在存储结束时需要报告 80 列数据时
您遇到 RDBMS 限制(索引限制、内存限制、
SQL 连接 COST 限制、失控分页和数据进入虚拟
当数据库认为它应该使用 HASH 而不是使用 NESTED LOOPS 时进行内存/交换)
我已经标准化 LIVE 数据(数据输入用户 24/7 全天候写入和读取)
突然想到优化中间表占用空间的方法
在存储过程中使用(在第 2 步)将查找复合主键并分配
每个都有一个唯一的 id(代理 PK),从而用 1 列引用 n 列。然后,我
将在第 2 步结束时重构此数据并准备好
在第 3 步开始时写回。这将增加更多处理
第 2 步,但会复制更少的数据。也需要调试
更多步骤(将 id 追溯到中间的实际数据
执行完成后的表数据)
有没有人遇到过使用冗长存储过程的场景?
是否有人在
中创建了代理键(用单列 PK 替换复合 PK)
仅在存储过程中使用的中间表?
这在执行时间和期间使用的内存/空间方面是否得到了回报
执行?
【问题讨论】:
-
你说的是十一千行存储过程吗??
-
每次执行存储过程时:您要为其创建临时表的数据量是多少?直观地说,一个 11 000 行的存储过程听起来像是一种错误的方法。您能否编写一个 C# 应用程序,在计算过程中处理内存中所需的数据?
-
@Simen S 它实际上是数据库大小的两倍。当存储过程已经在 SQL 中进行非常复杂的数据处理(处理数据块)时,C# 逐行处理就不是一个选项
-
创建代理键(用单列 PK 替换复合 PK)不是规范化。这甚至不是正常化(如果你是英国人):)
-
@n8wrl 是的,你没看错。这些要求需要根据大量评级因素(大量计数、分组、SQL 函数、时间计算)进行大量计算(它是为保险业 TPA 编写的)。输入不是微不足道的,结果也不是。并不是要开始一场语言大战,但在 SQL 中,我需要做的所有事情都需要 1/2 的时间来阅读和修改。它很简洁。一切都在块中处理。它是声明性的,它干净且容易。这在 C# 中是无法管理的。
标签: sql sql-server oracle stored-procedures normalization