2010-11-09 131 views
1

我想知道爲什麼我的select語句在更新從一個表到另一個表的值時比我的update語句快幾個數量級,而不是從一個表中選擇值到另一個表。下面的例子說明,我可以運行我的select語句很快基於另一個表更新值到一個錶慢

select customers.name, countries.country 
from customers 
inner join countries on customers.countrycode = countries.countrycode 

但是我寫的更新語句(我相當肯定的是同樣的事情)發生量級更長的時間來完成我的問題。

update customers 
set customers.country = countries.country 
from customers 
inner join countries on customers.countrycode = countries.countrycode 

有什麼建議?

UPDATE:

下面是SELECT語句

|--Hash Match(Inner Join, HASH:([countries].[countrycode])=([Testing].[dbo].[customers].[countrycode]), RESIDUAL:(@countries.[countrycode] as [countries].[countrycode]=[Testing].[dbo].[customers].[countrycode])) 
     |--Table Scan(OBJECT:(@countries AS [countries])) 
     |--Table Scan(OBJECT:([Testing].[dbo].[customers])) 

下面的計劃是在UPDATE語句的計劃

|--Table Update(OBJECT:([Testing].[dbo].[Customers]), SET:([Testing].[dbo].[Customers].[Country] = @countries.[country] as [countries].[country])) 
     |--Top(ROWCOUNT est 0) 
      |--Stream Aggregate(GROUP BY:([Bmk1000]) DEFINE:([countries].[country]=ANY(@countries.[country] as [countries].[country]))) 
       |--Nested Loops(Inner Join, WHERE:(@countries.[countrycode] as [countries].[countrycode]=[Testing].[dbo].[Customers].[countrycode])) 
         |--Table Scan(OBJECT:([Testing].[dbo].[Customers])) 
         |--Table Scan(OBJECT:(@countries AS [countries])) 
+0

請問您可以發佈兩個查詢的計劃嗎?運行'SET SHOWPLAN_TEXT ON GO',然後運行查詢。 – Quassnoi 2010-11-09 17:01:26

回答

3

首先,UPDATE改變表格。這意味着如果在更新過程中出現檢查點,則事務日誌和數據文件本身上的數據文件重爲I/O

A DML操作沒有辦法比查詢更快。

二,你如何測量速度? SQL Server可以比所有記錄更快地返回第一條記錄(甚至不成比例地更早),具體取決於使用的查詢計劃以及如何填充緩存。

更新:

從你的計劃,我可以看到沒有UNIQUE鍵被定義countries.countrycode

SQL Server必須找到一個值爲每個countrycode分配給customers(即使存在實際上是一個單值),並確實爲這個Stream Aggregate

countries.countrycode上創建一個PRIMARY KEY

+0

上面列出的選擇操作大約需要3秒鐘,更新語句需要超過10分鐘。 – 2010-11-09 16:58:35

+0

救命恩...非常感謝! – 2010-11-09 17:42:22

1

指標

如果你有多個索引customers,每更新一行更新每個索引。這是一個資源密集型的過程。索引加速選擇,但減慢更新/插入(通常)。

+0

如果客戶表上有外鍵約束(比如customer_id),情況會是這樣嗎?我的客戶表上沒有任何索引,但外鍵來自的表格有很多。 – 2010-11-09 17:00:04

+1

@Anish Patel - 如果您沒有使用索引更改該表中的列,那麼不會,據我所知應該不會影響它。你有'客戶'的聚集索引嗎?如果不是,請添加一個,看看它如何影響它。 – JNK 2010-11-09 17:04:28

0

選擇有(如果數據尚未在內存中)I/O Out of Disk。

更新已讀取I/O,寫入日誌I/O和寫入存儲器I/O。所以我想這應該需要更長的時間。

但是你應該嘗試創建一個聚集索引,如果你可以選擇一個纖細的聚集索引鍵,那可能會加快速度。