目前我有以下问题: 我有一个UPDATE语句,用SELECT / COUNT(*) - 函数的结果更新几条记录。
例如
UPDATE Table
SET Field1 = Function1(...),
Field2 = Function2(...),
Field3 = Function3(...)
此查询需要数小时。 但如果我这样做:
UPDATE Table
SET Field1 = Function1(...)
UPDATE Table
SET Field2 = Function2(...)
UPDATE Table
SET Field3 = Function3(...)
它在不到一个小时的时间内完成。
我在网上搜索了一些与参数嗅探有关的东西,这似乎与我的问题有关。所以我为我的所有函数添加了一个OPTION(RECOMPILE),它对性能有所帮助,但并不多。 有谁知道为什么会这样?我显然可以坚持多个UPDATE语句,但我仍然想知道为什么会发生这种情况。有什么想法吗?
编辑:函数是标量函数
答案 0 :(得分:3)
将标量函数重写为表值函数。
避免使用TVF进行逐行行为
标量函数的一个问题是它们对结果集中的每一行都执行一次。虽然这对于小结果集来说不是问题,但是当我们的查询返回大量行时,它就成了问题。我们可以使用TVF解决这个问题。
更多参考资料:
Scalar functions, inlining, and performance: An entertaining title for a boring post - Adam Machanic
如果您为整个表获取count(*)
以跟踪总行数,则可以使用系统视图来获取行计数,而不是为每个表执行select count(*) from t
。
select
[schema] = object_schema_name(o.object_id)
, [table] = o.name
, [index] = i.name
, p.partition_number
, [row_count] = p.rows
, [index_type] = i.type_desc
from sys.partitions p
inner join sys.indexes i
on p.object_id = i.object_id
and p.index_id = i.index_id
and i.index_id < 2
inner join sys.objects o
on i.object_id = o.object_id
where o.is_ms_shipped=0
--order by schema, table, index
在rextester上返回此内容:http://rextester.com/URW59373
+--------+-------------------+----------------------+------------------+-----------+------------+
| schema | table | index | partition_number | row_count | index_type |
+--------+-------------------+----------------------+------------------+-----------+------------+
| dbo | Pilots | PK_Pilots | 1 | 3 | CLUSTERED |
| dbo | Planes | PK_Planes | 1 | 2 | CLUSTERED |
| dbo | Flights | PK_Flights | 1 | 2 | CLUSTERED |
| dbo | Pilots_on_flights | PK_Pilots_on_flights | 1 | 4 | CLUSTERED |
| dbo | table1 | NULL | 1 | 0 | HEAP |
| dbo | table2 | NULL | 1 | 0 | HEAP |
+--------+-------------------+----------------------+------------------+-----------+------------+