0

如果 SQL 直接使用或由 NHibernate 创建,可能有很大的“在/不在([1 到 100 个参数])”条件下,将参数填充到特定限制是否有意义,具有有限数量的查询计划?

参数是 int/number,DBMS 是 MSSQL 或 Oracle。通过 sp_executesql/executeimmediate 调用查询以强制执行查询计划缓存。

通常,这样的查询对于同一查询最多有 100 个查询计划。几个这样的查询可能会很快填满缓存,或者根本不使用缓存的查询计划而导致性能下降。

用户可以通过重复最后一个值来填充参数列表,直到达到一定数量的参数?

据我所知,MSSQL 和 Oracle 通过字符串相等来识别已知查询,从而为每个不同数量的参数生成不同的查询计划。

(值当然是参数,而不是串联的数字)。

SELECT * FROM MyTable WHERE Id in (4001, 4002, 4003, ... , 4055, 4056)

有 56 个参数,更改为:

SELECT * FROM MyTable WHERE Id in (4001, 4002, 4003, ... , 4055, 4056, 4056, 4056, 4056, 4056)

通过重复值 4056 具有 60 个参数,所有长“in”列表的长度为 50、60、70、80、90、100。只剩下不到 10 个参数。

对于这样一个多达 100 个参数的查询,将有 10 个查询计划用于 10 到 100 个参数,加上 9 个查询计划用于 1 到 9 个参数(无填充)。

编辑:我发现 NHibernate(3.1.0.4 或更高版本)和 SQL Server,batch-size="200" 实际上将参数列表拆分为多个语句,具有固定长度的参数列表。例如,带有 118 个 ID 参数的 select 和 batch-size="200" 可以作为三个带有 100、12 和 6 个 ID 的选择发送,而不是一个带有 118 个 ID 的选择。这与我想要的类似,batch-size="200" 不是 200 个不同的 SQL 字符串,因此查询计划会随着时间的推移而累积,但只有一个较小的数字,可能是 16 个。每个参数计数在 1 之间似乎有一个 SQL和 12,然后是具有 25、50 和 100 个参数的语句。也许用重复的值填充可能更有效,但这是确保查询计划重用的好方法。

4

1 回答 1

0

如果您有大量查询参数都表示相同的值类型,它们应该是表中的列,而不是参数列表。

如果它们足够静态,请将它们放在过滤器表中并执行以下操作:

SELECT t.*
FROM MyTable t
INNER JOIN FilterTable f ON t.Id = f.Id

如果它们是完全动态的,则使用表值参数。在 SQL Server 2008 中,我可以将表值参数从 NHibernate 传递给我的存储过程。如何在 Oracle 中实现相同的功能

于 2013-07-12T18:30:55.747 回答