2009-12-01 147 views
2

我的有限SQL知識促使本文發表!SQL(服務器)更新性能

我有一個運行一系列更新的存儲過程。
有6個更新語句,可以很好地將其嵌入到一個大型更新語句中,但我不知道這對性能意味着什麼。

表基本信息: 6張表被擊中。其中3個永遠不會有超過5000個記錄,其中3個無限期增長(目前約爲1-2百萬條記錄,正確索引等)。加入所有表格並執行一個大規模更新聲明與將其保持爲6個獨立更新有速度優勢嗎?

我正在尋找最有效的方式來做到這一點,即使它削弱了一秒。

謝謝。

編輯:

我向所有人道歉。我只更新一個表,但驗證所有6的數據以更新一個表。 (即檢查table2.somevalue是否爲空,然後將table1中的記錄標記爲「錯誤」)

+0

爲什麼不自己嘗試並使用查詢分析器來檢查處理時間? – Jrud

+0

你可以發佈你的更新陳述和你打的表嗎?如果您正在根據加入6的結果更新1個表格,或者如果您想要找出更新6個不同表格的方式(如Cade下面提到的是不可能的,只用一個表格Sql 2008和特定場景中的例外) – chadhoc

+0

@JRud:我使用分析器,結果非常接近。我只是想從周圍的人那裏獲得一些其他的專業知識,以防萬一錯過了一些東西。 – SlackerCoder

回答

4

如果可以合併它們,那麼是的,你應該合併它們。

如果從單個表更新多列,然後將它們結合起來,如:

UPDATE mytable 
SET foo = bar, fizz = buzz, whiz = bang 
WHERE zing > 2081 

,而不是

UPDATE mytable SET foo = bar WHERE zing > 2081 
UPDATE mytable SET fizz = buzz WHERE zing > 2081 
UPDATE mytable SET whiz = bang WHERE zing > 2081 

這幾乎是3倍的效率,因爲它只有經過表一次。

更新不同表格中的字段必須單獨完成(如Cade Roux提到的,它甚至不可能在的同時執行)。

即使您使用的是複雜聯接,也一次只能更新一個表。例如:

UPDATE AccountHistory 
SET LastPurchaseDate = i.PurchaseDate 
FROM Account a 
INNER JOIN AccountHistory h ON a.AccountID = h.AccountID 
INNER JOIN Invoices i ON i.AccountID = a.AccountID 
WHERE i.PurchaseDate > '2009-11-30' 

只有AccountHistory在這裏被更改,即使源數據是通過連接訪問的。

0

即使存在,我也不建議修改基本表模式以將性能提高一小部分。如果一個變化會在性能上發生很大的變化(如雙倍或三倍),那麼在性能至關重要的情況下,這可能是值得的,但是,對於幾乎所有的現代數據庫軟件包,都可以使用許多其他技術在不改變基本表模式的情況下提高性能。您可以添加爲您的應用程序使用的查詢類型定製的索引。在其他技術中,您可以添加索引視圖(Oracle中的物化視圖)。您可以垂直和/或水平分區表。在SQL Serve中,您可以對小表進行「PIN」編碼,以便它們始終保持在內存中。

1

使用提供的數據無法得到很好的答案 - 您需要了解每次更新時是否標準索引以及組合對更新複雜性所做的工作。

我認爲6次更新(如果需要,在一次事務中)比1次更新更容易理解 - 所以這是一個更好的解決方案,您可以優化每次更新以儘可能快地完成。

JRud評論是好的 - 你總是可以嘗試兩種方式和比較時間。

1

顯着的性能改進可以典型地通過分組查詢時查詢來自[遠程]客戶來實現,。在你的情況下,多個查詢來自一個存儲過程,因此很容易就是本地請求,並且將它們結合起來的好處根本不會很重要。

此外,當在更新的情況下檢查SQL文件,,這是不可能寫在哪一個時間修改多個表的查詢......

不過,既然你出現尋求效率最高的方式,您需要嘗試各種可能性(在一組代表性數據輸入下)查看特定更改的效果。在缺乏關於您的具體情況的更多細節的情況下,很難提供更有針對性的信息。

一小和通用提示:
在參照「大」表「正確索引」中提及,是一個提醒,當談到更新(一般多寫操作,如刪除和插入),索引可能更多地是一種資產的責任,在性能方面。

4

這甚至不可能(在單個UPDATE語句中同時更新多個表)在T-SQL中。

BOL

table_name的

是表更新的名稱。 如果該表不在當前服務器或數據庫的 中,或者不是當前用戶擁有的 ,則可以使用 鏈接的服務器,數據庫和所有者 名稱限定該名稱。

VIEW_NAME

是更新視圖的名稱。由view_name引用的視圖必須爲 可更新。 UPDATE語句所做的修改不會影響 多於 視圖的FROM子句中引用的多個基表 。

+0

+1你擊敗了我!我只是在文檔中檢查這種多表更新查詢的語法...... – mjv

+0

我假設OP通過跨6個表的連接結果更新單個表,但這可能是錯誤的假設,我要求澄清。 – chadhoc

+0

雖然他的意思是改變計劃......當然,你不能在一個更新語句中更新多個表...... – Dani

0

您是試圖改善存儲過程的整體性能還是減少更新所花費的時間?

如果我更擔心併發(減少鎖定時間)而不是整體性能,我會將鍵值選擇到變量或臨時表中。然後,我使用UPDATE中的變量或臨時表。 「重點」可以顯着提高UPDATE性能。

警告:使用這種方法需要很好地理解你的系統是如何工作的。這種方法最大的風險是增加了死鎖的可能性。