SQL性能调优 - 更新查询

时间:2015-03-12 10:19:34

标签: sql sql-server

在下面的更新查询中,我有两个子查询。两者都是相同的,除了它正在拾取的列(ColumnA,ColumnB)。单个子查询提供超过100,000条记录,从中选择第一行。

但是存在性能问题,因为可以将两个子查询组合到单个查询中。

如何组合。

UPDATE TABLE1 SET 
LOWEST_RATE = (SELECT TOP 1 ColumnA from Table2 WHERE Table2.Currency = Table1.Currency),
DIFF_RATE = (SELECT TOP 1 ColumnB from Table2 WHERE Table2.Currency = Table1.Currency)

4 个答案:

答案 0 :(得分:0)

使用可更新的CTE和row_number()为每种货币只获得一行:

;with x as (
select Currency, ColumnA, ColumnB,
row_number() over(partition by Currency order by ...) as rn
from Table1
),
y as (
select t1.*, t2.*
from Table1 t1
join x t2 on t1.currency = t2.currency and t2.rn = 1
)
update y
set 
lowest_rate = ColumnA,
diff_rate = ColumnB

如果您真的不介意表2中的哪一行,请使用任何列而不是...

答案 1 :(得分:0)

也许你可以做这样的事情

UPDATE TABLE1 SET 
              LOWEST_RATE = (SELECT TOP 1 ColumnA),
              DIFF_RATE = (SELECT TOP 1 ColumnB)
from Table2 INNER JOIN  Table1 
on Table2.Currency = Table1.Currency

答案 2 :(得分:0)

如果没有错,您的correlated subqueries可以转换为INNER JOIN。试试这个。

UPDATE A 
SET    LOWEST_RATE = B.columna, 
       DIFF_RATE = C.columnb 
FROM   table1 A 
       INNER JOIN (SELECT Max(columna) ColumnA, 
                          currency 
                   FROM   table2 
                   GROUP  BY currency) B 
               ON A.currency = B.currency 
       INNER JOIN (SELECT Max(columnb) ColumnB, 
                          currency 
                   FROM   table2 
                   GROUP  BY currency) C 
               ON A.currency = C.currency 

答案 3 :(得分:0)

使用CROSS APPLY是处理通过CTE进行更新的相关子查询的有效方法。

;WITH cte
    AS (
        SELECT
            table1.lowest_rate 
          , table1.diff_rate 
          , ca1.lowest_one
          , ca2.highest_one
        FROM table1
        CROSS APPLY (
                SELECT TOP (1)
                    ColumnA
                FROM table2
                WHERE table1.Currency  = table2.Currency 
                ORDER BY
                    ColumnA  ASC
            ) ca1 (lowest_one)
        CROSS APPLY (
                SELECT TOP (1)
                    ColumnB
                FROM table2
                WHERE table1.Currency  = table2.Currency 
                ORDER BY
                    ColumnB  DESC
            ) ca2 (highest_one)
        )
UPDATE cte
SET
    lowest_rate = lowest_one
  , diff_rate = highest_one
;