update auditdata set TATCallType='12',TATCallUnit='1' from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
當我上面查詢它需要超過10分鐘執行。緩慢更新(主鍵)
什麼錯在這個
Auditdata.ID
是主鍵..
如果我運行更新命令也更新索引??? 是這個原因讓更新的速度很慢
update auditdata set TATCallType='12',TATCallUnit='1' from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
當我上面查詢它需要超過10分鐘執行。緩慢更新(主鍵)
什麼錯在這個
Auditdata.ID
是主鍵..
如果我運行更新命令也更新索引??? 是這個原因讓更新的速度很慢
查看您的評論,主表包含的行少於臨時表。
嘗試使用EXISTS子句(或在某種意義上,比較減少至行(數即150萬)
update auditdata set TATCallType='12',TATCallUnit='1'
from auditdata auditdata
WHERE EXISTS
(SELECT id from Auditdata_sms_12 a_sns WHERE a_sns.id = auditdata.ID)
這樣做是爲了限制比較
編輯:AuditdataSMS12應該有關於ID索引能夠快速獲得該行。這就是你實際上是在尋找爲某個ID的表。
更新 我再次閱讀初始查詢,你不更新主ID字段後實現,但另外2個數據字段。請重新閱讀我的回覆的第一個陳述並相應發表評論。抱歉。
是否有您所更新要麼字段中定義一個聚集索引?聚簇索引有很多好處,我不知道它們,但它們可能在更新期間導致大量的性能命中。我的理解是,聚集索引的更新可能導致整個索引必須重新編譯。如果表中有很多數據,這肯定會導致您的問題。
此外,還要確保有在表上沒有觸發器。如果觸發器行爲不正確,可能會導致相同的性能下降。
多久簡單的選擇(例如
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
)以及它找到了多少條記錄?
如果SQL Server必須通讀所有500萬點的記錄,或更新一百萬條記錄,並沒有足夠的內存或足夠快的硬件,那麼就可能沒有什麼你與查詢。
你可能需要監視SQL服務器的硬件和更要看查詢計劃,看看有什麼位佔用的時間。
這裏有一些東西在玩。
首先,SQL語句看起來破裂。更新中的「FROM」子句旨在用作JOIN'd更新。由於您使用硬編碼值更新行,因此無需這樣做。
其次,更深奧的是,如果索引是正確的,就像你說的那樣,那麼你可能是在處理初始寫入或事務日誌區域的緩慢磁盤I/O(在Oracle中爲撤消,登錄SQL Server等)。
作爲一個健全的檢查,我會做兩件事。一,只更新尚未設置條件的行。許多DBMS產品將愉快地爲不改變的行執行物理磁盤I/O(儘管許多不)。嘗試與極限。
二,以較小的批次應用更新。這對於日誌爭用和較慢的磁盤確實有幫助。
所以,像下面的最初嘗試:
UPDATE auditdata
SET TATCallType = '12'
, TATCallUnit = '1'
FROM auditdata
WHERE TATCallType <> '12'
AND TATCallUnit <> '1'
AND EXISTS(SELECT *
FROM Auditdata_sms_12 a_sns
WHERE a_sns.id = auditdata.ID)
如果你想要做的批次,在SQL Server中這是很容易:
SET ROWCOUNT 2000
UPDATE ...
(run continually in a loop via T-SQL or by hand until @@ROWCOUNT = 0)
SET ROWCOUNT 0
哪個DBMS?桌子大概有多大?這是剛剛開始發生在現有的查詢,還是這是一個新的查詢? – 2009-07-14 16:16:30
- 你的主鍵是什麼數據類型? - 你在這張桌子上有什麼索引? – 2009-07-14 16:17:56
桌子有多大?如果這是100,000,000行,並且它必須更新每一行,那麼它對你有什麼索引無關緊要:這將需要一段時間。 – Eric 2009-07-14 16:20:15