对于Sql 2008中的查询,希望这只是一个涉及性能优化的简单问题。
我曾为那些使用Stored Procs进行ETL过程以及他们的一些网站的公司工作过。我已经看到了他们需要根据一组有限的键值检索特定记录的场景。我已经看到它以3种不同的方式处理,通过下面的伪代码说明。
动态Sql,用于连接字符串并执行它。
EXEC('SELECT * FROM TableX WHERE xId IN (' + @Parameter + ')'
使用用户定义的函数将分隔的字符串拆分为表格
SELECT * FROM TableY INNER JOIN SPLIT(@Parameter) ON yID = splitId
使用XML作为参数而不是分隔的varchar值
SELECT * FROM TableZ JOIN @Parameter.Nodes(xpath) AS x (y) ON ...
虽然我知道在第一个片段中创建动态sql是一个坏主意,原因很多,但我的好奇心来自最后两个例子。在我的代码中进行尽职调查是否更为熟练,以便通过XML传递此类列表(如代码段3)或者更好地分隔值并使用udf来处理它?</ p>
答案 0 :(得分:5)
现在有第4个选项 - table valued parameters,您可以将值表实际传递给sproc作为参数,然后像通常的表变量那样使用它。我更喜欢这种方法而不是XML(或CSV解析方法)
我不能引用所有不同方法之间的性能数据,但这是我要尝试的 - 我建议对它们进行一些真正的性能测试。
修改强>
关于TVP的更多信息。为了将值传递给您的sproc,您只需定义一个SqlParameter(SqlDbType.Structured) - 可以将其值设置为任何IEnumerable,DataTable或DbDataReader源。所以,大概你已经在某种列表/数组中有了值列表 - 你不需要做任何事情来将它转换成XML或CSV。
我认为这也使得sproc更清晰,更简单,更易于维护,提供了一种更自然的方式来实现最终结果。其中一个要点是SQL在基于集合/不循环/非字符串操作活动中表现最佳。
这并不是说它会通过传递大量值来表现出色。但是对于较小的集合(最多约1000),应该没问题。
答案 1 :(得分:2)
UDF
调用比使用内置函数拆分XML
要贵一些。
但是,每次查询只需执行一次,因此性能差异可以忽略不计。