这完全取决于您正在做什么和测量什么。不过,我希望您需要使用不同的值才能获得真实的结果。
缓存
如果您每次都发送相同的值,您可能可以保证您感兴趣的特定行总是会被缓存(在缓冲区缓存中、在文件系统缓存中、在 SAN 中缓存等)如果可能的输入集很大,这可能不太现实。另一方面,如果有少量潜在输入,并且您有理由相信感兴趣的行将始终被缓存(例如,如果您知道在调用您的服务之前发生的一些其他活动将导致您感兴趣的数据在调用服务之前缓存在内存中)那么也许这是一个现实的假设。
优化
忽略缓存,我们可以看看优化器如何处理这两种情况。如果您正在生成带有嵌入文字的 SQL 查询(这是一种在 Oracle 中特别有害但非常常见的不良做法),那么您正在生成不同的 SQL 语句。就甲骨文而言
SELECT *
FROM emp
WHERE deptno = 10
是与
完全不同的陈述
SELECT *
FROM emp
WHERE deptno = 20
您可以调整一些设置(即cursor_sharing)以要求 Oracle 将这两个查询视为相同的查询(通过让 Oracle 强制它们使用绑定变量)但这并非没有缺点,通常只推荐当您在重构应用程序以正确使用绑定变量时尝试将创可贴应用于编写不佳的应用程序。
假设您在应用程序中使用绑定变量生成查询,准备语句,然后在多次执行查询之前绑定不同的值,即
SELECT *
FROM emp
WHERE deptno = :1
然后您将进入直方图、绑定变量窥视和自适应游标共享领域。这可能会涉及很多,并且很大程度上取决于您使用的 Oracle 版本、您使用的版本以及您如何配置优化器以使其工作。我将尝试在这里提供一个简化的高级概述 - 如果您想深入研究其中一个,我们可能需要一个单独的问题。
直方图
默认情况下,优化器假定数据是等间距和等可能的。因此,例如,如果deptno 列有 50 个不同的值,则优化器默认假定每个值的可能性相同。对于大多数列来说,这可能是一个非常合理的假设,但对于所有列来说显然不是合理的。例如,如果我有一张包含所有现役军人的表,其中一列是 birth_year,那么 1994 年(20 年前)的 birth_year 行将比 1934 年(80 年前)多得多.在这些情况下,您可以收集相关列的直方图,以便告诉优化器数据分布不均匀,并让优化器收集有关哪些值更常见以及它们的常见程度的信息。
优化器不关心您为绑定变量值传递的值,除非您的谓词中的一列上有直方图(我暂时忽略您传递的值的可能性超出范围)。
绑定变量窥视
如果您在一个或多个列上确实有直方图,那么 Oracle(9.1 及更高版本,如果有记忆的话)将“窥视”为绑定变量传入的第一个值,并将该值与直方图一起使用来确定所有后续执行的最佳计划。这在绝大多数情况下工作得相当好,但是当 Oracle 偷看一个“坏”值并生成一个对那一次执行有效但对所有未来都很糟糕的计划时,它偶尔会导致令人毛骨悚然的痛苦问题(以及很多咒骂)处决。 Tom Kyte 关于the database that has to be restarted if it's rainy on a Monday morning 的故事总结了这一点。如果您在列上有一个直方图,并且您可能传入的不同值可能会从不同的查询计划中受益,那么您可能需要考虑绑定变量窥视以确定以不同顺序传入值是否会产生任何性能问题.
自适应光标共享
在最近的版本中(如果内存服务于 11.1 和更高版本)并且根据您的配置,Oracle 可以使用 adaptive cursor sharing 来维护单个语句的多个查询计划,并为特定的绑定变量值使用最合适的版本,即这是一个更复杂的绑定变量窥视版本,它窥视你传入的每组值,并确定它是否与其他一组值足够接近以使用先前生成的计划,或者它是否需要计算新价值观的新计划。弄清楚什么是“足够接近”以及它如何与各种功能相互作用以确保计划的稳定性,这本身就是一个相当复杂的话题。