当涉及到 Sql 2008 中的查询时,这希望只是一个涉及性能优化的简单问题。

我曾为那些在 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 来处理它更好?

最佳答案

现在有第四个选项 - table valued parameters ,您实际上可以将值表作为参数传递给 sproc,然后像通常使用表变量一样使用它。我更喜欢这种方法而不是 XML(或 CSV 解析方法)

我无法在所有不同方法之间引用性能数据,但这是我会尝试的一种 - 我建议对它们进行一些真正的性能测试。

编辑:
关于 TVP 的更多信息。为了将值传递到您的 sproc,您只需定义一个 SqlParameter (SqlDbType.Structured) - 这个值可以设置为任何 IEnumerable、DataTable 或 DbDataReader 源。因此,大概您已经拥有某种列表/数组中的值列表 - 您无需执行任何操作即可将其转换为 XML 或 CSV。

我认为这也使 sproc 更清晰、更简单、更易于维护,提供了一种更自然的方式来实现最终结果。要点之一是 SQL 在基于集合/非循环/非字符串操作事件中表现最佳。

这并不是说它在传入大量值时会表现出色。但是对于较小的集(最多约 1000),它应该没问题。

关于Sql优化 : Xml or Delimited String,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2245007/

10-17 02:21