SweetPotato Asked: 2020-08-26 03:21:28 +0800 CST2020-08-26 03:21:28 +0800 CST 2020-08-26 03:21:28 +0800 CST 为什么要更新存储过程? 772 是否有重要的理由重新编译存储过程? 当然,数据库中的数据会随着时间而变化,并且某些存储过程的结果集可能会因基础数据的变化而有所不同。但是除非表结构发生变化,否则存储过程应该永远是好的吗? 我说的是 Sybase ASE 15。 stored-procedures sybase 1 个回答 Voted Best Answer David Spillett 2020-08-26T05:47:30+08:002020-08-26T05:47:30+08:00 数据库中的数据随时间变化 这是通常的原因。虽然编译存储过程的概念是特定于实现的,但它通常涉及为过程和/或形成它的各个语句生成查询计划,并将其存储以供以后重用(以保存该部分过程在每次重复调用该过程的时间)。 随着数据的增长,每个表/索引中的数据平衡可能会发生变化,使得上次编译过程时的最佳计划现在比其他选项效率低得多,因此过程将不再像它一样执行可以。例如,如果在创建(或上次编译)过程时表中只有几行,则扫描可能比一次或多次搜索更有效,但以后可能不再如此。此外,首先触摸哪个索引最有效可能会随着时间的推移而变化,特别是对于宽表上的查询和连接多个表的查询。 数据库引擎通常会内置一些启发式算法,以在大量数据更改以及结构更改后导致重新编译,但这些算法通常在操作上非常保守,因此有时需要手动启动重新编译。与决定何时对索引统计直方图重新采样所涉及的启发式方法非常相似(通常会在查询计划决策和存储过程中提供这些信息)。 有时带有参数的 procs 需要不同的计划才能对不同的输入有效 - 有时在某些情况下总是重新编译是有益的,因为差异如此之大以至于您不想冒险使用慢速缓存计划(在 MS SQL ServerWITH RECOMPILE提示用于处理此类情况,或者OPTION (RECOMPILE)用于更细粒度方法的每个语句)。足够复杂以至于这是一个主要问题的程序通常是“代码异味”,这意味着您的设计需要调整,尽管它们并不总是很容易避免。 重新编译存储过程、函数、视图和其他编程对象的最后一个原因是,当其他地方的更改以破坏依赖性检查的方式进行时,这意味着在实际需要时不会发生自动重新编译。例如: 您有一个使用表格视图的过程。 有人丢弃并重新创建视图(而不是使用ALTER VIEW)。 依赖信息 proc->view 现在丢失了。 表已更改。 由于依赖链被破坏,引擎不知道过程中的语句可能需要重新编译,这意味着过程可能开始完全失败或给出不正确的结果。 重新编译(在此阶段或重新创建视图之后)可以解决此问题。
这是通常的原因。虽然编译存储过程的概念是特定于实现的,但它通常涉及为过程和/或形成它的各个语句生成查询计划,并将其存储以供以后重用(以保存该部分过程在每次重复调用该过程的时间)。
随着数据的增长,每个表/索引中的数据平衡可能会发生变化,使得上次编译过程时的最佳计划现在比其他选项效率低得多,因此过程将不再像它一样执行可以。例如,如果在创建(或上次编译)过程时表中只有几行,则扫描可能比一次或多次搜索更有效,但以后可能不再如此。此外,首先触摸哪个索引最有效可能会随着时间的推移而变化,特别是对于宽表上的查询和连接多个表的查询。
数据库引擎通常会内置一些启发式算法,以在大量数据更改以及结构更改后导致重新编译,但这些算法通常在操作上非常保守,因此有时需要手动启动重新编译。与决定何时对索引统计直方图重新采样所涉及的启发式方法非常相似(通常会在查询计划决策和存储过程中提供这些信息)。
有时带有参数的 procs 需要不同的计划才能对不同的输入有效 - 有时在某些情况下总是重新编译是有益的,因为差异如此之大以至于您不想冒险使用慢速缓存计划(在 MS SQL Server
WITH RECOMPILE
提示用于处理此类情况,或者OPTION (RECOMPILE)
用于更细粒度方法的每个语句)。足够复杂以至于这是一个主要问题的程序通常是“代码异味”,这意味着您的设计需要调整,尽管它们并不总是很容易避免。重新编译存储过程、函数、视图和其他编程对象的最后一个原因是,当其他地方的更改以破坏依赖性检查的方式进行时,这意味着在实际需要时不会发生自动重新编译。例如:
ALTER VIEW
)。依赖信息 proc->view 现在丢失了。
由于依赖链被破坏,引擎不知道过程中的语句可能需要重新编译,这意味着过程可能开始完全失败或给出不正确的结果。