Parameterized SQL - in / not in with fixed numbers of parameters, for query plan cache optimization?

血红的双手。 提交于 2020-01-16 14:30:44

问题


If SQL is used directly or created by NHibernate, with possibly big "where in / not in ([1 to 100 parameters])" conditions, does it make sense to fill up parameters to certain limits, to have a limited number of query plans?

Parameters are int/number, DBMS is MSSQL or Oracle. The queries are called via sp_executesql/executeimmediate to enforce query plan caching.

Normally, such a query would have up to 100 query plans for the same query. Several such queries might quickly fill up the cache, or result in poor performance by not using cached query plans at all.

A user may fill up the parameter list by repeating the last value, until a certain number of parameters is reached?

As far as I know, MSSQL and Oracle identify known queries by string equality, resulting in a different query plan for each different number of parameters.

(values would of course be parameters and not concatenated numbers).

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

with 56 parameters, change to:

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

having 60 parameters by repeating value 4056, with all long "in" lists having lengths of 50, 60, 70, 80, 90, 100. Only less than 10 params will be left.

For such a query with up to 100 parameters, there would be 10 query plans for 10 to 100 parameters, plus 9 query plans for 1 to 9 parameters (no fill).

EDIT: I found that NHibernate (3.1.0.4 or later) and SQL Server, with batch-size="200" actually splits parameter lists into multiple statements, with fixed length param lists. For example, select with 118 ID parameters and batch-size="200" may be sent as three selects with 100, 12 and 6 IDs, instead of one with 118 IDs. This is similar to what I wanted, batch-size="200" not with 200 different SQL strings and thus query plans accumulating over time, but only a smaller number, perhaps 16. There seemed to be one SQL for each parameter count between 1 and 12, then statements with 25, 50 and 100 parameters. Maybe filling up with a repeated value -can- be more efficient, but this is a good way to ensure query plan reuse.


回答1:


If you have a large number of query parameters that all represent the same value type, they should be a column in a table, not a parameter list.

If they are sufficiently static, put them in a filter table and do:

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

If they are completely dynamic, then use a Table Valued Parameter. 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



来源:https://stackoverflow.com/questions/17620105/parameterized-sql-in-not-in-with-fixed-numbers-of-parameters-for-query-plan

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!