自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

禁用 SQL 游標(biāo),告訴你外面聽不到的原因

運(yùn)維 數(shù)據(jù)庫運(yùn)維
索引是用到了,但是每次更新,更新的那行跑到 IDX_SALES_AMT_QUTA 索引后面去了,導(dǎo)致無限在更新 SalesAmountQuota 的值,直到大于 50萬”L 覺得平時(shí)太強(qiáng)調(diào) seek 索引了,但沒有全面透徹的講解索引其實(shí)也有好心辦壞事兒的時(shí)候。

[[433798]]

文末本文轉(zhuǎn)載自微信公眾號「有關(guān)SQL」,作者Lenis。轉(zhuǎn)載本文請聯(lián)系有關(guān)SQL公眾號。

周六清晨,東方剛剛露白。

L 早早來到辦公室,捎帶上最愛的熱焦瑪。今天會是一場苦戰(zhàn),計(jì)劃了兩個(gè)月的上線產(chǎn)品,今天發(fā)布。他需要極其敏捷的腦子。另外,只要 L 還在喝著咖啡,說明 DB 肯定是沒問題的,也能起到一點(diǎn)安慰軍心的作用吧。所以大事件面前,L 總是拿著星巴克晃悠。誰都猜不到他到底是愛喝,還是臭顯擺。

F 晃著小腦袋過來了,Release 已經(jīng)開始了 1 小時(shí),按理 DB 部分部署早該完成。這次稍微超過 L 的預(yù)期,但沒有告警,大家也就沒有太放心上。直到 F 過來找 L, 低頭問了下:

“L, 有段更新數(shù)字的腳本,跑了40多分鐘還沒結(jié)束。理論上只有100多萬數(shù)據(jù)會被更新,花這么長時(shí)間,不知道是否正常?”

F 是個(gè)五年陳了,該經(jīng)歷的也都經(jīng)歷了,如今冒出這么個(gè)疑問,L 也是慎重起來。“哪段腳本?”

  1. SET NOCOUNT ON ; 
  2.  
  3.  
  4. DECLARE @SalesQuotaKey Bigint 
  5.  
  6.  
  7. DECLARE MY_Cur Cursor For 
  8. SELECT TOP 1000000 SalesQuotaKey 
  9. FROM FactSalesQuotaAudit  
  10. WHERE SalesAmountQuota<500000 
  11. ORDER BY SalesAmountQuota ASC 
  12.  
  13.  
  14. OPEN MY_Cur   
  15. FETCH NEXT FROM MY_Cur INTO @SalesQuotaKey 
  16.  
  17.  
  18. WHILE(@@FETCH_STATUS = 0 ) 
  19. BEGIN 
  20. UPDATE FactSalesQuotaAudit  
  21. SET SalesAmountQuota = SalesAmountQuota + 100000 
  22.         WHERE SalesQuotaKey = @SalesQuotaKey  
  23.  
  24. FETCH NEXT FROM MY_Cur INTO @SalesQuotaKey  
  25. END 
  26.  
  27.  
  28. CLOSE MY_Cur  
  29. DEALLOCATE MY_Cur 

“嗯,這段貌似會有問題,就看索引是怎么建的”L 常說,trouble shooting 就像是做偵探,有時(shí)候,話其實(shí)是說給自己聽的,“如果在 SalesAmountQuota 上加索引的話,這就有危險(xiǎn)”

“果不其然”,L打開 SSMS窗口,找到了索引定義:

  1. CREATE Unique CLUSTERED  index PK_SalesQuotaKey  
  2. ON FactSalesQuotaAudit(SalesQuotaKey) 
  3.  
  4. CREATE INDEX IDX_SALES_AMT_QUTA  
  5. ON FactSalesQuotaAudit(SalesAmountQuota) 

為保分析無誤,L 還是先看了下現(xiàn)狀:

  1. SELECT TOP 1000000 SalesQuotaKey 
  2. FROM FactSalesQuotaAudit  
  3. WHERE SalesAmountQuota<500000 
  4. ORDER BY SalesAmountQuota ASC 

“目前來看,這段腳本還在繼續(xù)跑著”

“但執(zhí)行計(jì)劃顯示正確跑了 SalesAmountQuota 的索引呢?”F 不解

“其實(shí)這里真是這個(gè)索引惹的禍”

“索引是用到了,但是每次更新,更新的那行跑到 IDX_SALES_AMT_QUTA 索引后面去了,導(dǎo)致無限在更新 SalesAmountQuota 的值,直到大于 50萬”L 覺得平時(shí)太強(qiáng)調(diào) seek 索引了,但沒有全面透徹的講解索引其實(shí)也有好心辦壞事兒的時(shí)候。所以索引要給 F 畫個(gè)腦圖:

“更新完的數(shù)據(jù)又排回索引了,而游標(biāo)一直在往前讀滿足條件的數(shù)據(jù),你可以細(xì)想下這個(gè)有趣的過程”看到 F 頻頻點(diǎn)頭,L 自以為已經(jīng)講的很明晰了。

"終于跑完了," F 眼見監(jiān)控 Dashboard 上的那個(gè)超長 session 消失了,臉色也開始和悅起來。

“大錯即將發(fā)生”L 一盆冷水澆過去,F(xiàn) 又不惑,90后小姑娘的臉色,真是跟天氣一樣,瞬間都能千變?nèi)f化。

  1. SELECT COUNT(*)  
  2. FROM FactSalesQuotaAudit WITH(NOLOCK) 
  3. WHERE SalesAmountQuota<500000 

“你看,結(jié)果是0,肯定不是你想要的結(jié)果吧。你原意肯定是在不滿50萬額度的那些銷售上,再加十萬,現(xiàn)在全部都加到了50萬。這是典型的 Halloween 問題”

“那,怎么辦?”F 面對這段讓她面紅耳赤的游標(biāo),簡直奔潰

“用臨時(shí)表,先把數(shù)據(jù)更新對了,再找最優(yōu)解決方法”

"那什么是 Halloween 問題?"

故事發(fā)生在 50年前的一個(gè)晚上,1970年左右,IBM 的一群研究員決定給不滿25000美金年薪的雇員,增加10% 的薪水。

他們寫了一段 SQL,大意是這樣的:

  1. update Employee 
  2. Set Salary = Salary * (1 + 10%) 
  3. where Salary < 25000 

結(jié)果等他們運(yùn)行完畢,發(fā)現(xiàn)所有的年薪不滿 25000 美金的雇員,他們的薪水統(tǒng)統(tǒng)加到了 25000.

 

例如,原本是 15000薪水的雇員和 8000 美金年薪的雇員,他們的薪水更新完了之后,都到了25000 美金。這一天正好是 10月31日,Halloween Day. 所以被稱為 Halloween Problem.

 

責(zé)任編輯:武曉燕 來源: 有關(guān)SQL
相關(guān)推薦

2013-12-09 13:22:58

2015-11-06 09:41:03

圖標(biāo)可視化

2019-11-28 08:59:03

SQL注入網(wǎng)絡(luò)攻擊網(wǎng)絡(luò)安全

2014-11-03 09:21:21

戴爾

2020-12-04 15:07:44

比特幣區(qū)塊鏈技術(shù)

2020-02-24 12:34:21

JuliaPython編程語言

2011-08-01 14:33:44

SQL

2020-11-18 19:25:01

2022-06-29 08:32:04

游標(biāo)MySQL服務(wù)器

2010-07-26 11:27:43

SQL Server打

2019-08-28 08:08:47

數(shù)據(jù)科學(xué)家數(shù)據(jù)工程師數(shù)據(jù)科學(xué)

2013-12-22 23:20:04

田溯寧亞信企業(yè)

2010-09-08 16:48:27

SQL循環(huán)游標(biāo)

2010-09-17 13:40:43

SQL更新

2010-07-23 18:33:57

SQL Server游

2013-05-20 16:09:39

SQL Server

2012-07-03 16:56:12

Hadoop

2011-06-30 09:37:08

JavaDB2SQL

2019-12-30 22:24:50

大數(shù)據(jù)機(jī)器學(xué)習(xí)文章

2021-10-09 20:41:32

人工智能AI安防監(jiān)控
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號