如果直接使用SQL或由NHibernate创建SQL,可能有大的“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个参数,以及9个查询计划用于1到9个参数(无填充)。
编辑:我发现NHibernate(3.1.0.4或更高版本)和SQL Server(batch-size =“200”)实际上将参数列表拆分为多个语句,具有固定长度的参数列表。例如,选择118个ID参数,批量大小=“200”可以作为三个选择发送100,12和6个ID,而不是一个具有118个ID。这与我想要的类似,batch-size =“200”没有200个不同的SQL字符串,因此查询计划随着时间累积,但只有一个较小的数字,可能是16.每个参数计数之间似乎有一个SQL在1之间和12,然后是25,50和100参数的语句。也许填写重复的值 - 可以更高效,但这是确保查询计划重用的好方法。
答案 0 :(得分:0)
如果您有大量的查询参数都表示相同的值类型,它们应该是表中的列,而不是参数列表。
如果它们足够静态,请将它们放在过滤表中并执行:
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