日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server中的重要观点

發(fā)布時間:2025/7/14 数据库 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server中的重要观点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

以下為重要觀點:

1、通過把數(shù)據(jù)庫設置成讀已提交快照,在read committed隔離級別下,讀不會阻塞寫,寫也不會阻塞讀,通過嘗試這個觀點是正確的。

2、當連接1請求了共享鎖,2請求了獨占鎖,3請求了共享鎖,4請求了更新鎖時,這四個請求都會進入鎖的請求隊列中,書上說SQL Server的鎖隊列,基本上是按照先進先出的規(guī)則,但是會考慮鎖的兼容性,所以這個時候可能1、3、4這3個請求的鎖是兼容的,所以這3個請求會先處理,這個得嘗試一下




一個優(yōu)化方面的重要的觀點

網(wǎng)友的提問:
大牛們,加了一個or,為什么執(zhí)行計劃由哈希匹配變成嵌套循環(huán)?http://bbs.csdn.net/topics/390599501

select count(*) from t1 where a1='1' and a2 in(select a2 from t2)


select count(*) from t1 where a1='1' and (a2 in(select a2 from t2) or a2='2')

表t1超過100萬條數(shù)據(jù),語句1執(zhí)行時間為1秒,語句2超過80秒,請問為什么,語句2該怎樣修改?


下面是我的回答:

建議把查詢改寫成關聯(lián)的,inner join或者是left join,其實要想明白,為什么加了a2='2'后,執(zhí)行計劃變化了,這個很難,因為這個是由SQL Server的優(yōu)化器決定的,我們很難猜測優(yōu)化器在一堆的判斷當中為什么選了nested loop 而不選hash join。

但如果你寫成inner join或者left join的時候,如果速度不佳,你可以通過添加查詢提示,比如hash:inner hash join

其實本質上就是手動給SQL Server的優(yōu)化器建議,建議他采用hash join,之所以微軟會提供這種查詢提示,就是已經(jīng)預料到會有你所遇到的問題,所以才提供了這種可以由你來進行微調的技術。


?

下面是一個關于數(shù)據(jù)庫設計的觀點

下面是網(wǎng)友的一個問題:http://bbs.csdn.net/topics/390631703?page=1#post-395959332

關于倉儲系統(tǒng)的方案設計,以下為現(xiàn)有倉庫表的設計(部分表):

TAB/裝車單:
字段:(裝車單號,倉庫ID,倉庫編碼,倉庫名稱,...創(chuàng)建人NAME,創(chuàng)建時間,修改人NAME,修改時間...)

TAB/裝車單明細表:
字段:(裝車單號,貨物ID,貨物名稱,...創(chuàng)建人NAME,創(chuàng)建時間,修改人NAME,修改時間...)


TAB/采購單:
字段:(采購單號,...創(chuàng)建人NAME,創(chuàng)建時間,修改人NAME,修改時間...)

TAB/采購單明細表:
字段:(進貨商ID,進貨商NAME,采購部門ID,采購部門NAME,...創(chuàng)建人NAME,創(chuàng)建時間,修改人NAME,修改時間...驗貨人NAME,驗貨時間)

?

首先這個不我設計的,我覺那個人這樣的設計的好處就是為了查詢方便(不用做關聯(lián)查詢嵌套查詢什么的就能獲得要的數(shù)據(jù)),但是一旦部門名稱或者管理員名稱(即便可能不修改 但不是絕對的)等等會影響到所有使用這些數(shù)據(jù)的表。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
我的解決方案

我看到這個庫時候感覺里面太多太多的表都都是這樣的,舉個最明顯的例子,創(chuàng)建人NAME 好多表都存的是 管理員的NAME 而非ID。

我覺的除了把管理員NAME之類的刪除,都換成外鍵。除此 像裝車單里的倉庫編碼、倉庫名稱、等;裝車明細表里的貨物名稱;采購單明細里的采購部門NAME,進貨商NAME都統(tǒng)統(tǒng)刪除 只保留引用的外鍵ID進行設計

之所以這樣修改是為了解決數(shù)據(jù)冗余問題,但后期在查詢數(shù)據(jù)時候會涉及更多的嵌套查詢關聯(lián)查詢才能解決。不知道各位老蝦怎么看我這樣的處理方案或者給個更好的意見,多謝
===============================================================================

?

下面是我的回復:

其實,你對于表的修改意見,是有道理的。

因為,關系數(shù)據(jù)庫系統(tǒng),在設計時,有所謂3NF,一般都要達到這個第三范式,這樣能夠減少數(shù)據(jù)的冗余。

而且,實際上不僅能夠減少冗余,而且這樣做的好處是由于是通過外鍵來引用基表的id,修改也方便了,

比如,當你的倉庫名稱變化了,你只需要去修改,這些業(yè)務表所引用的,基表里面的倉庫名稱。

而你們公司現(xiàn)在的系統(tǒng),如果你有10個業(yè)務表,都有倉庫名稱這個字段,一旦只要有一個倉庫的名稱變化了,那么你就得通過倉庫編號,來連接基表,然后再update這10個表的倉庫名稱,那是非常麻煩的。

應該說,你們公司現(xiàn)在系統(tǒng)的數(shù)據(jù)存儲方式是采用了反向規(guī)范化,也就是冗余化存儲。

你希望采用規(guī)范化,而你們公司原來的系統(tǒng)采用的是范規(guī)范化。

規(guī)范化的好處上面說了,就是減少數(shù)據(jù)冗余,修改非常容易。
而反向規(guī)范化的好處,就是不用子查詢,或者關聯(lián)多的表,查詢的性能會好。

總結:
我覺得到底采用哪種方式,這需要你自己權衡,如果你的系統(tǒng),很少有更新倉庫名稱,也就是很少更新這些基表數(shù)據(jù),那么為了提高查詢的性能,而且也不用每次寫查詢,關聯(lián)N多基表,那么就還是采用原來的方式。這種方式,在互聯(lián)網(wǎng)的應用中比較多,傳統(tǒng)的業(yè)務用的不多。

如果系統(tǒng)中會更新這些倉庫名稱,那么還是建議采用外鍵id的方式,來修改這些表的設計,當然啦,語句可能得寫的比較復雜,因為我原來的公司就是都采用外鍵id的,由于這種外鍵很多,公司設計了一個字典表,

比如:dict_table 里面存放了幾乎所有的外鍵id,所引用的id,那么我們公司有一個store表,里面有一堆的id,上面渠道id,公司id,組織id,經(jīng)銷商id,層級id,性質id等,于是乎,為了取得這些客戶的渠道、公司、組織、經(jīng)銷商、層級、性質,就得關聯(lián)dict_table 至少6次,也就是

select 字段列表
from store
left join dict_table
left join dict_table
left join dict_table
left join dict_table
left join dict_table
left join dict_table

就是這樣,經(jīng)常一個查詢,得關聯(lián)10-15個表左右,語句寫的非常復雜。

所以,呵呵,最后還是得樓主,按照你們公司的特殊情況,業(yè)務特點,來選擇,到底是去除冗余,或者是去除部分冗余。



還有下面的,關于數(shù)據(jù)庫設計的:

我也試了,如果把數(shù)據(jù)拆分成列,那么到時候,比如:屬性-值,拆分成2行數(shù)據(jù),一行存屬性,一行存列,
這樣看上去倒是好一點,但是在查詢的時候,還是得行轉列,比較麻煩。


其實設計表,就是得考慮:性能,業(yè)務,占用存儲,開發(fā)速度。

我原來的公司,需要非常快的開發(fā)速度,于是,就把不同業(yè)務的數(shù)據(jù),放到一個表中,通過增加一個func_code字段,來區(qū)分是不同功能產(chǎn)生的,然后后面是一堆字段,A業(yè)務用xx字段,B業(yè)務用yy字段,其他都是空著的,這樣的話,非常方便開發(fā),在理解業(yè)務的時候,也很容易,不同業(yè)務,用不同的字段。

但是,如果你不懂業(yè)務,就會很迷惑,看不懂,怎么一眼看過去,一堆沒用的字段放在那兒,全是null。

也想過拆分,但是這樣也麻煩,就是剛才說的,開發(fā)的難度就上去了,而且性能也不會太好,因為你得做動態(tài)的行轉列,每個業(yè)務用到的字段個數(shù),和字段名稱,都不完全一樣,這可非常的麻煩。

所以,你一開始想的還是對的,這種表的設計,雖然看著,有很多null值,但是開發(fā)上就比較容易,性能也不錯。



關于通過游標和循環(huán)的方式來處理數(shù)據(jù)的問題:


其實用循環(huán)和游標,之所以對性能有影響,根本的原因在于,處理數(shù)據(jù)的方式,也就是取出1條數(shù)據(jù),然后處理,處理完成后,再取出下一條,

如果你的表有1000w條數(shù)據(jù),那么就得循環(huán)1000w次,效率肯定是非常低的。

同樣的,如果單純的sql語句,之所以性能相對較好的原因在于,他是以集合為單位來處理數(shù)據(jù),也就是批處理,一次能把所有的數(shù)據(jù)都處理好。

當然,有時候,由于業(yè)務邏輯非常復雜,可能需要寫多個語句,每個語句先把中間的結果插入到一個臨時表中,然后最后再對臨時表進行處理,這也是一個變通的辦法,但盡量不要用游標或者是循環(huán)來處理數(shù)據(jù),因為效率比較低。


?

轉載于:https://www.cnblogs.com/momogua/archive/2012/02/05/8304637.html

總結

以上是生活随笔為你收集整理的SQL Server中的重要观点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。