在一个Update中调用多个函数时查询效果不佳,但在使用多个更新时性能良好

时间:2017-02-08 12:23:33

标签: sql-server performance

目前我有以下问题: 我有一个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语句,但我仍然想知道为什么会发生这种情况。有什么想法吗?

编辑:函数是标量函数

1 个答案:

答案 0 :(得分:3)

将标量函数重写为表值函数。

  

避免使用TVF进行逐行行为

     

标量函数的一个问题是它们对结果集中的每一行都执行一次。虽然这对于小结果集来说不是问题,但是当我们的查询返回大量行时,它就成了问题。我们可以使用TVF解决这个问题。

更多参考资料:

如果您为整个表获取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       |
+--------+-------------------+----------------------+------------------+-----------+------------+