使用未确定数量的参数时,如何避免动态SQL?

Ste*_*ham 7 sql t-sql sql-server stored-procedures sql-match-all

我有一个类似StackOverflow的标记系统,用于我正在处理的数据库.我正在编写一个存储过程,该过程根据WHERE子句中未确定数量的标记查找结果.可以有0到10个标签之间的任何位置来过滤结果.例如,用户可能正在搜索标记为"apple","orange"和"banana"的项目,并且每个结果必须包含所有3个标记.我的查询变得更加复杂,因为我还在处理标记的交叉引用表,但出于这个问题的目的,我不会讨论.

我知道我可以做一些字符串操作并为exec()函数提供一个查询来处理这个问题,但我宁愿不解决与动态SQL相关的性能问题.我认为最好是SQL缓存存储过程的查询计划.

在这种情况下,您使用了哪些技术来避免动态SQL?

根据大众需求,这是我正在使用的查询:

SELECT ft.[RANK], s.shader_id, s.page_name, s.name, s.description, s.download_count, s.rating, s.price FROM shader s 
INNER JOIN FREETEXTTABLE(shader, *, @search_term) AS ft ON s.shader_id = ft.[KEY]
WHERE EXISTS(SELECT tsx.shader_id FROM tag_shader_xref tsx INNER JOIN tag t ON tsx.tag_id = t.tag_id WHERE tsx.shader_id = s.shader_id AND t.tag_name = 'color')
AND EXISTS(SELECT tsx.shader_id FROM tag_shader_xref tsx INNER JOIN tag t ON tsx.tag_id = t.tag_id WHERE tsx.shader_id = s.shader_id AND t.tag_name = 'saturation')
ORDER BY ft.[RANK] DESC
Run Code Online (Sandbox Code Playgroud)

这是功能性但硬编码.你会看到我设置它来寻找'颜色'和'饱和度'标签.

Hen*_*pel 13

有关此问题以及类似问题的详细概述,请参阅:http://www.sommarskog.se/dyn-search-2005.html

具体到您的问题是这里的部​​分:http://www.sommarskog.se/dyn-search-2005.html#AND_ISNOTNULL

还要考虑到(直接)动态解决方案不一定比(可能是复杂的)静态解决方案慢,因为查询计划仍然可以缓存:请参阅http://www.sommarskog.se/dyn-search-2005.html #dynsql

因此,您必须仔细测试/测量您的选项与实际数据量,考虑真实的查询(例如,使用一个或两个参数进行搜索可能比使用十个搜索更常见,等等)


编辑:提问者给出了一个很好的理由在评论中对此进行优化,因此将"过早"警告移开:

然而,(标准;)警告词适用:这闻起来很像过早的优化!- 你确定这个sproc会被调用,通常情况下使用动态SQL会明显变慢(也就是说,与应用程序中发生的其他事情相比)?