【问题标题】:Parameterized SQL - in / not in with fixed numbers of parameters, for query plan cache optimization?参数化 SQL - in / not in 具有固定数量的参数,用于查询计划缓存优化?
【发布时间】:2013-07-11 07:15:43
【问题描述】:

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

参数为 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 个参数的查询计划,以及针对 1 到 9 个参数的 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 个参数的语句。也许用重复的值填充可能更有效,但这是确保查询计划重用的好方法。

【问题讨论】:

    标签: sql nhibernate caching parameters sql-execution-plan


    【解决方案1】:

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

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

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

    如果它们是完全动态的,则使用表值参数。 In SQL Server 2008 I am able to pass table-valued parameter to my stored procedure from NHibernate.How to achieve the same in Oracle

    【讨论】:

    • 不幸的是,NHibernate 目前似乎不支持表参数。链接的示例不是真正的 NHibernate 实现(数据模型),而只是通过 NHibernate 以经典 ADO.NET 样式进行的普通 SQL 调用。 Id 值都是由客户端逻辑选择的,这里没有过滤表是有意义的。无论如何,如果 NHibernate 通过它的数据模型支持表参数那就太好了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    相关资源
    最近更新 更多