冗长的SQL存储过程,其中表存储的列越来越多

时间:2011-08-08 19:06:06

标签: sql sql-server oracle stored-procedures normalization

此问题适用于用SQL-92编写的存储过程 即Oracle PL / SQL,SQL Server T-SQL或DB2 SQL

我正在维护一个11000行的存储过程 我发现在存储过程结束时,我需要报告80列数据。

此存储过程中有3个不同的阶段。

  1. 数据收集(将实时表中的数据复制到存储过程中间表中)
    我需要进行数据收集以保持一致性,因为第30行的LIVE数据(即在成员表中)可能在存储过程执行到达行10,000时发生了变化 此处维护提交状态原子性(在所有需要的数据都被复制之前不提交)
  2. 计算(大量SQL,复杂到足以使游标或视图无法完成工作)
  3. 回写永久表(发票,AR,付款)
    此处维护提交状态原子性(在所有需要的数据都被复制之前不提交)
  4. “中间”表仅用于存储过程 它们被编入索引,用于连接线但没有
    PK / FK参照完整性约束或唯一索引
    因为这些会大大减慢执行速度 指回实况数据(即流动)

    当您到达存储的结尾时需要报告的80列数据时 针对RDBMS限制运行的程序(索引限制,内存限制,
    SQL加入COST限制,失控分页和数据转为虚拟
    内存/交换,当DB认为它应该使用HASH而不是使用NESTED LOOPS时

    我已将LIVE数据标准化(数据录入用户可以24/7写入和读取)

    我想到了优化中间表占用空间的方法 在存储过程中使用(在步骤2)将是找到复合主键并分配
    每个唯一的id(代理PK),从而引用n列1列。然后,我 将在第2步结束时重新构建这些数据并准备好 回写在步骤3的开头。这将增加更多的处理 第2步,但会复制较少的数据。调试也需要 更多步骤(追溯id到中间的实际数据) 执行完成后的表数据)

    是否有人使用冗长的存储过程遇到这种情况? 是否有人创建了代理键(用单列PK替换复合PK) 只在存储过程中使用的中间表?

    在执行时间和内存/空间方面取得了成效 执行?

4 个答案:

答案 0 :(得分:2)

我认为我的1400行触发器很长!

我可以看到代理键在连接中的位置比复合PK更快。但是对于任何这么复杂的事情,我认为你只需要尝试两种方式。

你可以减少80列吗?我想我问你是否使用了select * with join,其中join fieds将在​​查询中重复,并且可以免除。

答案 1 :(得分:1)

为什么不尝试编写SSIS包。除了写入临时表之外,您的大部分计算都将在SSIS内存中,而不会打扰数据库。

您可以根据需要分解您的包装,并且可以更加维护。

BTW,11K sproc是疯了......不能帮助它,不得不说: - )

答案 2 :(得分:1)

我已经构建了一些长度的SProcs,而且我总是选择 Indentity 列代理键。是否有可能重新考虑所做的工作并为每个中间步骤创建单独的临时表?

过去我必须这样做。最后,我将 缝合 “所有单独的临时表放入我的最终输出中。

答案 3 :(得分:0)

“我需要进行数据收集以保持一致性,因为第30行的LIVE数据(即成员表中)可能在存储过程执行到10,000行时发生了变化”

在Oracle中,您可以查看DBMS_FLASHBACK(或SERIALIZABLE隔离级别)以获得此级别的一致性。闪回查询可能会避免您需要复制所有数据。

我为数据迁移做了类似的练习 - 很多临时表。要检查的一个因素是在临时表的适当时间点收集统计数据。如果这些表通常是空的,那么统计数据可能会在最后搞砸了。