




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
怎樣提高數(shù)據(jù)庫查詢效率
2.應(yīng)盡量避免在where子句中對字段進行null值推斷,否則將導(dǎo)致引擎放棄使用索引而進
行全表掃描,如:
selectidfromtwherenumisnull
能夠在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:
selectidfromtwherenum=0
3.應(yīng)盡量避免在where子句中使用!=或者v>操作符,否則將引擎放棄使用索引而進行全表
掃描。
4.應(yīng)盡量避免在where子句中使用or來連接條件,否則將導(dǎo)致引擎放棄使用索引而進行全
表掃描,如:
selectidfromtwherenum=10ornum=20
能夠這樣查詢:
selectidfromtwherenum=10
unionall
selectidfromtwherenum=20
5.in與notin也要慎用,否則會導(dǎo)致全表掃描,如:
selectidfromtwherenumin(l,2,3)
關(guān)于連續(xù)的數(shù)值,能用between就不要用in了:
selectidfromtwherenumbetween1and3
6.下面的查詢也將導(dǎo)致全表掃描:
selectidfromtwherenamelike'%abc%'
若要提高效率,能夠考慮全文檢索。
7.假如在where子句中使用參數(shù),也會導(dǎo)致全表掃描。由于SQL只有在運行時才會解析局
部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運行時;它務(wù)必在編譯時進行選擇。然而,
假如在編譯時建立訪問計?劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下
面語句將進行全表掃描:
selectidfromtwherenum=@num
能夠改為強制查詢使用索引:
selectidfromtwith(index(索弓|名))wherenum=@num
8.應(yīng)盡量避免在where子句中對字段進行表達式操作,這將導(dǎo)致引擎放棄使用索引而進行
全表掃描。如:
selectidfromtwherenum/2=100
應(yīng)改為:
selectidfromtwherenum=100*2
9.應(yīng)盡量避免在where子句中對字段進行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進行全表
掃描。如:
selectidfromtwheresubstring(name,1,3)='abc,—name以abc開頭的id
selectidfromtwheredatediff(day,createdate,,2005-ll-30,)=0—'2005-11-30'生成的id
應(yīng)改為:
selectidfromtwherenamelike'abc%'
selectidfromtwherecreatedate>=,2005-11-30'andcreatedate<,2005-12-1,
10.不要在where子句中的“=”左邊進行函數(shù)、算術(shù)運算或者其他表達式運算,否則系統(tǒng)
將可能無法正確使用索引。
11.在使用索引字段作為條件時,假如該索引是復(fù)合索引,那么務(wù)必使用到該索引中的第一
個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不可能被使用,同時應(yīng)盡可能的
讓字段順序與索引順序相一致。
12.不要寫一些沒有意義的查詢,如需要生成一個空表結(jié)構(gòu):
selectcoll,col2into#tfromtwhere1=0
這類代碼不可能返回任何結(jié)果集,但是會消耗系統(tǒng)資源的,應(yīng)改成這樣:
createtable
13.很多時候用exists代替in是一個好的選擇:
selectnumfromawherenumin(selectnumfromb)
用下面的語句替換:
selectnumfromawhereexists(select1frombwherenum=a.num)
14.并不是所有索引對查詢都有效,SQL是根據(jù)表中數(shù)據(jù)來進行查詢優(yōu)化的,當(dāng)索引列有大
量數(shù)據(jù)重復(fù)時,SQL查詢可能不可能去利用索引,如一表中有字段sex,male、female幾乎
各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
15.索引并不是越多越好,索引固然能夠提高相應(yīng)的select的效率,但同時也降低了insert
及update的效率,由于insert或者update時有可能會重建索引,因此如何建索引需要慎
重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應(yīng)考慮一些不常使
用到的列上建的索引是否有必要。
16.應(yīng)盡可能的避免更新clustered索引數(shù)據(jù)列,由于clustered索引數(shù)據(jù)列的順序就是表記
錄的物理存儲順序,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整,會耗費相當(dāng)大的資源。
若應(yīng)用系統(tǒng)需要頻繁更新clustered索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為
clustered索弓I。
17.盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計為字符型,這會降低查詢與
連接的性能,并會增加存儲開銷。這是由于引擎在處理查詢與連接時會逐個比較字符串中每
一個字符,而關(guān)于數(shù)字型而言只需要比較一次就夠了。
18.盡可能的使用varchar/nvarchar代替char/nchar,由于首先變長字段存儲空間小,能夠
節(jié)約存儲空間,其次關(guān)于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。
19.任何地方都不要使用select*fromt,用具體的字段列表代替“*”,不要返回用不到的任
何字段。
20.盡量使用表變量來代替臨時表。假如表變量包含大量數(shù)據(jù),請注意索引非常有限(只有
主鍵索引)。
21.避免頻繁創(chuàng)建與刪除臨時表,以減少系統(tǒng)表資源的消耗。
22.臨時表并不是不可使用,適當(dāng)?shù)厥褂盟鼈兡軌蚴鼓承├谈行?,比如,?dāng)需要重復(fù)引
用大型表或者常用表中的某個數(shù)據(jù)集時。但是,關(guān)于一次性事件,最好使用導(dǎo)出表。
23.在新建臨時表時,假如一次性插入數(shù)據(jù)量很大,那么能夠使用selectinto代替create
table,避免造成大量log以提高速度;假如數(shù)據(jù)量不大,為了緩與系統(tǒng)表的資源,應(yīng)先
createtable,然后insert。
24.假如使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先truncate
table,然后droptable,這樣能夠避免系統(tǒng)表的較長時間鎖定。
25.盡量避免使用游標(biāo),由于游標(biāo)的效率較差,假如游標(biāo)操作的數(shù)據(jù)超過1萬行,那么就應(yīng)
該考慮改寫。
26.使用基于游標(biāo)的方法或者臨時表方法之前,應(yīng)先尋找基于集的解決方案來解決問題,基
于集的方法通常更有效。
27.與臨時表一樣,游標(biāo)并不是不可使用。對小型數(shù)據(jù)集使用FAST_FORWARD游標(biāo)通常要
優(yōu)于其他逐行處理方法,特別是在務(wù)必引用幾個表才能獲得所需的數(shù)據(jù)時。在結(jié)果集中包含
“合計”的例程通常要比使用游標(biāo)執(zhí)行的速度快。假如開發(fā)時間同意,基于游標(biāo)的方法與基
于集的方法都能夠嘗試一下,看哪一種方法的效果更好。
28.在所有的存儲過程與觸發(fā)器的開始處設(shè)置SETNOCOUNTON,在結(jié)束時設(shè)置SET
NOCOUNTOFF。無需在執(zhí)行存儲過程與觸發(fā)器的每個語句后向客戶端發(fā)送
DONE_IN_PROC消息、。
29.盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力。
30.盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理
1:影響最大的是在數(shù)據(jù)庫端家索引。
2:假如數(shù)據(jù)庫字段很多,建議使用Select字段列表的方式而不使用Select*
3:請使用TQuery或者TADOQuery,同時WHERE語句一定要建立索引,盡量少使用TTable
或者TADOTable.
4:多使用存儲過程。
5:關(guān)于ORACLE與SYBASE數(shù)據(jù)庫要使用BDE,而關(guān)于MSSQLSERVER使
用ADO方式連接。
同時,關(guān)于ORACLE與SQLSERVER,OLEDB的效率要比ADO效率高。BDE應(yīng)該
是效率比較低下的一種方式,這個在開發(fā)過程中我們有過比較。
另外:盡量保持建立的數(shù)據(jù)庫連接,不必每次都重新連接數(shù)據(jù)庫。這在SQLSERVER
與ACCESS下表現(xiàn)不明顯,但是在ORACLE中就非常明顯,由于ORACLE的建鏈時間非
常長,大約有2秒鐘,而SQL與ACCESS大約只需0.01秒。
在查詢語句中,要考慮where語句中的字段順序。
盡量不用ORDERBY語句(數(shù)據(jù)量比較大的時候)
關(guān)于一個有超過百萬條記錄的數(shù)據(jù)表,怎么才能提高效率。
VB+ADO+SQLSERVER2000.
我能想到的有建立索引、使用存儲過程。還有什么其他辦法嗎?
拆表,升級硬件。檢索時盡量帶參數(shù),要用的數(shù)據(jù)才檢出來。
對關(guān)聯(lián)字段建索引:
優(yōu)化SQL語句,減少或者避免多表連結(jié)。
添加內(nèi)存、CPU
建立視圖
充分利用高速緩存
充分利用索引與SQL語句語法
無關(guān)緊要的查詢能夠進行臟讀
建索引的選擇務(wù)必結(jié)合SQL查詢、修改、刪除語句的需要,通常的說法是在WHERE里經(jīng)
常出現(xiàn)的字段建索引。假如在WHERE經(jīng)常是幾個字段一起出現(xiàn)而且是用AND連接的,那
就應(yīng)該建這幾個字段一起的聯(lián)合索引,而且次序也需要考慮,通常是最常出現(xiàn)的放前面,重
復(fù)率低的放前面。
如有一張員工表,與部門表.1、直接用select*from員工表,部門表where員
工表.部門ID=部門.ID。2、select*from員工表。然后當(dāng)程序選擇到某個員工
后,再根據(jù)部門的ID來選擇部門信息。
這兩種方法,哪個效率高
假如是需要同時顯示所有員工的部門信息,則第一種方法好;
假如是用戶選中一個員工再帶出來該員工的部門信息,則第二種方法好;
在真正需要的時候才從數(shù)據(jù)庫提取數(shù)據(jù)
1。比較具有相同類型的列。
2。比較中應(yīng)盡量使索引列獨立。
3。在like模式的起始處不要使用通配符
比如:wherenamelike"%string%"
優(yōu)化為:wherenamelike"string%"
4o幫助優(yōu)化程序更好的評估索引的有效性
可用isamchk或者myisamchk的--analyze選項給優(yōu)化程序提供更好的信
息,以便分析鍵值的分布。
5。利用EXPLAIN檢驗優(yōu)化程序操作。
檢查用于查詢中的索引是否能很快的排除行
一個表中大概有20萬以上的條目(做音樂查詢)/
每次查詢都需要在這個表的兩個字段中查尋/(歌手與歌名)
如何提高效率?需要達到至少每秒30次的查詢/而cpu盡量占用低一點
請問如何處理數(shù)據(jù)庫與程序才能達到好的效果?
perl寫的程序。謝謝了。
表如下
id歌手歌曲url專輯格式性別xxxxxxxxx
xxx.
創(chuàng)建索引
建索引的目的是為了更好的查詢,但是不要盲目建索引,有的時候候適得其反。
遵循這樣的原則:
1.搜索的索引列,不一定是索要選擇的列
比如:selectcol_afromtbllleftjointbl2on
tbl1,col_b=tbl2.col_c
wherecol_d=expr
在這查詢重視合作索引列的是tbll.col_bandtbl2.col_candcol_d
2.使用唯一索引:關(guān)于唯一值的列,索引的效果最好,而具有多個重復(fù)值的列
其索引效果最差。
3.使用短索引:應(yīng)該指定一個前綴的長度,只要有可能就應(yīng)該這樣做
比如:varchar(lOO)列,對前10個或者者20個字符內(nèi),多數(shù)值是唯一的那就不要對
整個列索引。
4.利用最左索引:在創(chuàng)建n列的索引時,實際是創(chuàng)建了mysql可利用的n個索引,多列索
引能夠起幾個索引的作用,由于能夠利用索引中最左邊的列集來匹配。
ps:mysql不能使用不涉及左前綴的搜索。
5.不要過渡索引:
每個額外的索引都是要占額外的磁盤空間,并降低寫操作的性能。
6.考慮在列上進行比較的類型:
索引可用于與between運算。
查詢速度慢的原因很多,常見如下幾種:
1、沒有索引或者者沒有用到索引(這是查詢慢最常見的問題,是程序設(shè)計的缺陷)
2、I/O吞吐量小,形成了瓶頸效應(yīng)。
3、沒有創(chuàng)建計算列導(dǎo)致查詢不優(yōu)化。
4、內(nèi)存不足
5、網(wǎng)絡(luò)速度慢
6、查詢出的數(shù)據(jù)量過大(能夠使用多次查詢,其他的方法降低數(shù)據(jù)量)
7、鎖或者者死鎖(這也是查詢慢最常見的問題,是程序設(shè)計的缺陷)
8、sp」ock,sp_who,活動的用戶查看源因是讀寫競爭資源。
9、返回了不必要的行與列
10、查詢語句不好,沒有優(yōu)化
能夠通過如下方法來優(yōu)化查詢:
1、把數(shù)據(jù)、日志、索引放到不一致的UO設(shè)備上,增加讀取速度,往常能夠?qū)empdb應(yīng)
放在RAID0上,SQL2000不在支持。數(shù)據(jù)量(尺寸)越大,提高I/O越重要.
2、縱向、橫向分割表,減少表的尺寸(sp_spaceuse)
3、升級硬件
4、根據(jù)查詢條件,建立索引,優(yōu)化索引、優(yōu)化訪問方式,限制結(jié)果集的數(shù)據(jù)量。注意填充因子
要適當(dāng)(最好是使用默認(rèn)值0)。索引應(yīng)該盡量小,使用字節(jié)數(shù)小的列建索引好(參照索引
的創(chuàng)建),不要對有限的幾個值的字段建單一索引如性別字段
5、提高網(wǎng)速;
6、擴大服務(wù)器的內(nèi)存,Windows2000與SQLserver2000能支持4-8G的內(nèi)存。配置虛擬內(nèi)存:
虛擬內(nèi)存大小應(yīng)基于計算機上并發(fā)運行的服務(wù)進行配置。運行MicrosoftSQLServer?2000
時,可考慮將虛擬內(nèi)存大小設(shè)置為計算機中安裝的物理內(nèi)存的1.5倍。假如另外安裝了全
文檢索功能,并打算運行Microsoft搜索服務(wù)以便執(zhí)行全文索引與查詢,可考慮:將虛擬內(nèi)
存大小配置為至少是計算機中安裝的物理內(nèi)存的3倍。將SQLServermaxservermemory
服務(wù)器配置選項配置為物理內(nèi)存的1.5倍(虛擬內(nèi)存大小設(shè)置的一半)。
7、增加服務(wù)器CPU個數(shù);但是務(wù)必明白并行處理串行處理更需要資源比如內(nèi)存。使用并行
還是串行程是MsSQL自動評估選擇的。單個任務(wù)分解成多個任務(wù),就能夠在處理器上運行。
比如耽擱查詢的排序、連接、掃描與GROUPBY字句同時執(zhí)行,SQLSERVER根據(jù)系統(tǒng)的
負(fù)載情況決定最優(yōu)的并行等級,復(fù)雜的需要消耗大量的CPU的查詢最適合并行處理。但是
更新操作UPDATE,INSERT,DELETE還不能并行處理。
8、假如是使用like進行查詢的話,簡單的使用index是不行的,但是全文索引,耗空間。like
'a%,使用索引Hke,%a,不使用索引用like'%a%'查詢時,查詢耗時與字段值總長度成正比,
因此不能用CHAR類型,而是VARCHAR-關(guān)于字段的值很長的建全文索引。
9、DBServer與APPLicationServer分離:OLTP與OLAP分離
10、分布式分區(qū)視圖可用于實現(xiàn)數(shù)據(jù)庫服務(wù)器聯(lián)合體。聯(lián)合體是一組分開管理的服務(wù)器,但
它們相互協(xié)作分擔(dān)系統(tǒng)的處理負(fù)荷。這種通過分區(qū)數(shù)據(jù)形成數(shù)據(jù)庫服務(wù)器聯(lián)合體的機制能夠
擴大一組服務(wù)器,以支持大型的多層Web站點的處理需要。有關(guān)更多信息,參見設(shè)計聯(lián)合
數(shù)據(jù)庫服務(wù)器。(參照SQL幫助文件,分區(qū)視圖,)
a、在實現(xiàn)分區(qū)視圖之前,務(wù)必先水平分區(qū)表
b、在創(chuàng)建成員表后,在每個成員服務(wù)器上定義一個分布式分區(qū)視圖,同時每個視圖具有相
同的名稱。這樣,引用分布式分區(qū)視圖名的查詢能夠在任何一個成員服務(wù)器上運行。系統(tǒng)操
作如同每個成員服務(wù)器上都有一個原始表的復(fù)本一樣,但事實上每個服務(wù)器上只有一個成員
表與一個分布式分區(qū)視圖。數(shù)據(jù)的位置對應(yīng)用程序是透明的。
11、重建索弓IDBCCREINDEX,DBCCINDEXDEFRAG,收縮數(shù)據(jù)與日志DBCC
SHRINKDBQBCCSHRINKFILE.設(shè)置自動收縮日志.關(guān)于大的數(shù)據(jù)庫不要設(shè)置數(shù)據(jù)庫自動
增長,它會降低服務(wù)器的性能。在T-sql的寫法上有很大的講究,下面列出常見的要點:首
先,DBMS處理查詢計劃的過程是這樣的:
I、查詢語句的詞法、語法檢查
2、將語句提交給DBMS的查詢優(yōu)化器
3、優(yōu)化器做代數(shù)優(yōu)化與存取路徑的優(yōu)化
4、由預(yù)編譯模塊生成查詢規(guī)劃
5、然后在合適的時間提交給系統(tǒng)處理執(zhí)行
6、最后將執(zhí)行結(jié)果返回給用戶其次,看一下SQLSERVER的數(shù)據(jù)存放的結(jié)構(gòu):一個頁面
的大小為8K(8060)字節(jié),8個頁面為一個盤區(qū),按照B樹存放。
12、Commit與rollback的區(qū)別Rollback:回滾所有的事物。Commit:提交當(dāng)前的事物.沒有
必要在動態(tài)SQL里寫事物,假如要寫請寫在外面如:beginIranexec(@s)committrans或者
者將動態(tài)SQL寫成函數(shù)或者者存儲過程。
13、在查詢Select語句中用Where字句限制返回的行數(shù),避免表掃描,假如返回不必要的數(shù)據(jù),
浪費了服務(wù)器的I/O資源,加重了網(wǎng)絡(luò)的負(fù)擔(dān)降低性能。假如表很大,在表掃描的期間將表
鎖住,禁止其他的聯(lián)接訪問表,后果嚴(yán)重。
14、SQL的注釋申明對執(zhí)行沒有任何影響
15、盡可能不使用光標(biāo),它占用大量的資源。假如需要row-by-row地執(zhí)行,盡量使用非光
標(biāo)技術(shù),如:在客戶端循環(huán),用臨時表,Table變量,用子查詢,用Case語句等等。游標(biāo)能
夠按照它所支持的提取選項進行分類:只進務(wù)必按照從第一行到最后一行的順序提取行。
FETCHNEXT是唯一同意的提取操作,也是默認(rèn)方式??蓾L動性能夠在游標(biāo)中任何地方隨
機提取任意行。游標(biāo)的技術(shù)在SQL2000下變得功能很強大,他的目的是支持循環(huán)。有四個
并發(fā)選項READ_ONLY:不同意通過游標(biāo)定位更新(Update),且在構(gòu)成結(jié)果集的行中沒有鎖。
OPTIMISTICWITHvalueS:樂觀并發(fā)操縱是事務(wù)操縱理論的一個標(biāo)準(zhǔn)部分。樂觀并發(fā)操縱用
于這樣的情形,即在打開游標(biāo)及更新行的間隔中,只有很小的機會讓第二個用戶更新某一行。
當(dāng)某個游標(biāo)以此選項打開時,沒有鎖操縱其中的行,這將有助于最大化其處理能力。假如用
戶試圖修改某一行,則此行的當(dāng)前值會與最后一次提取此行時獲取的值進行比較。假如任何
值發(fā)生改變,則服務(wù)器就會明白其他人已更新了此行,并會返回一個錯誤。假如值是一樣的,
服務(wù)器就執(zhí)行修改。選擇這個并發(fā)選項OPTIMISTICWITHROWVERSIONING:此樂觀
并發(fā)操縱選項基于行版本操縱。使用行版本操縱,其中的表務(wù)必具有某種版本標(biāo)識符,服務(wù)
器可用它來確定該行在讀入游標(biāo)后是否有所更換。在SQLServer中,這個性能由timestamp
數(shù)據(jù)類型提供,它是一個二進制數(shù)字,表示數(shù)據(jù)庫中更換的相對順序。每個數(shù)據(jù)庫都有一個
全局當(dāng)前時間戳值:@@DBTSo每次以任何方式更換帶有timestamp列的行時、SQLServer
先在時間戳列中存儲當(dāng)前的@@DBTS值,然后增加@@DBTS的值。假如某個表具有
timestamp歹則時間戳?xí)挥浀叫屑?。服?wù)器就能夠比較某行的當(dāng)前時間戳值與上次提取
時所存儲的時間戳值,從而確定該行是否已更新。服務(wù)器不必比較所有列的值,只需比較
timestamp列即可。假如應(yīng)用程序?qū)]有timestamp列的表要求基于行版本操縱的樂觀并
發(fā),則游標(biāo)默認(rèn)為基于數(shù)值的樂觀并發(fā)操縱。SCROLLLOCKS這個選項實現(xiàn)悲觀并發(fā)操
縱。在悲觀并發(fā)操縱中,在把數(shù)據(jù)庫的行讀入游標(biāo)結(jié)果集時,應(yīng)用程序?qū)⒃噲D鎖定數(shù)據(jù)庫行。
在使用服務(wù)器游標(biāo)時,將行讀入游標(biāo)時會在其上放置一個更新鎖。假如在事務(wù)內(nèi)打開游標(biāo),
則該事務(wù)更新鎖將一直保持到事務(wù)被提交或者回滾;當(dāng)提取下一行時,將除去游標(biāo)鎖。假如
在事務(wù)外打開游標(biāo),則提取下一行時,鎖就被丟棄。因此,每當(dāng)用戶需要完全的悲觀并發(fā)操
縱時,游標(biāo)都應(yīng)在事務(wù)內(nèi)打開。更新鎖將阻止任何其它任務(wù)獲取更新鎖或者排它鎖,從而阻
止其它任務(wù)更新該行。然而,更新鎖并不阻止共享鎖,因此它不可能阻止其它任務(wù)讀取行,
除非第二個任務(wù)也在要求帶更新鎖的讀取。滾動鎖根據(jù)在游標(biāo)定義的SELECT語句中指定
的鎖提示,這些游標(biāo)并發(fā)選項能夠生成滾動鎖。滾動鎖在提取時在每行上獲取,并保持到下
次提取或者者游標(biāo)關(guān)閉,以先發(fā)生者為準(zhǔn)。下次提取時,服務(wù)器為新提取中的行獲取滾動鎖,
并釋放上次提取中行的滾動鎖。滾動鎖獨立于事務(wù)鎖,并能夠保持到一個提交或者回滾操作
之后。假如提交時關(guān)閉游標(biāo)的選項為關(guān),則COMMIT語句并不關(guān)閉任何打開的游標(biāo),而
且滾動鎖被保留到提交之后,以保護對所提取數(shù)據(jù)的隔離。所獲取滾動鎖的類型取決于游標(biāo)
并發(fā)選項與游標(biāo)SELECT語句中的鎖提示。鎖提示只讀樂觀數(shù)值樂觀行版本操縱鎖定
無提示未鎖定未鎖定未鎖定更新NOLOCK未鎖定未鎖定未鎖定未鎖定
HOLDLOCK共享共享共享更新UPDLOCK錯誤更新更新更新TABLOCKX錯誤
未鎖定未鎖定更新其它未鎖定未鎖定未鎖定更新*指定NOLOCK提示將使指定了
該提示的表在游標(biāo)內(nèi)是只讀的。
16、用Profiler來跟蹤查詢,得到查詢所需的時間,找出SQL的問題所在;用索引優(yōu)化器優(yōu)
化索引
17、注意UNion與UNionall的區(qū)別。UNIONall好
18、注意使用DISTINCT,在沒有必要時不要用,它同UNION一樣會使查詢變慢。重復(fù)的
記錄在查詢里是沒有問題的
19、查詢時不要返回不需要的行、列
20、用sp_configure'querygovernorcostlimit'或者者SETQUERY_GOVERNOR_COST_LIMIT
來限制查詢消耗的資源。當(dāng)評估查詢消耗的資源超出限制時,服務(wù)器自動取消查詢,在查詢
之前就扼殺掉。SETLOCKTIME設(shè)置鎖的時間
21、用selecttop100/10Percent來限制用戶返回的行數(shù)或者者SETROWCOUNT來限制操
作的行
22、在SQL2000往常,通常不要用如下的字句:"ISNULL","NOT",
"NOTEXISTS","NOTIN","NOTLIKE",and"LIKE'%500'",由于他們不走索引全是表掃描。
也不要在WHere字句中的列名加函數(shù),如Convert,substring等,假如務(wù)必用函數(shù)的時候,創(chuàng)
建計算列再創(chuàng)建索引來替代.還能夠變通寫法:WHERESUBSTRING(firstname,1,1)=改為
WHEREfirstnamelikehn%,(索引掃描),一定要將函數(shù)與列名分開。同時索引不能建得太多
與太大。NOTIN會多次掃描表,使用EXISTS、NOTEXISTS,IN,LEFTOUTERJOIN來
替代,特別是左連接,而Exists比IN更快,最慢的是NOT操作.假如列的值含有空,往常它
的索引不起作用,現(xiàn)在2000的優(yōu)化器能夠處理了。相同的是ISNULL,"NOT","NOTEXISTS",
"NOTIN”能優(yōu)化她,而”<>”等還是不能優(yōu)化,用不到索引。
23、使用QueryAnalyzer,查看SQL語句的查詢計劃與評估分析是否是優(yōu)化的SQL。通常
的20%的代碼占據(jù)了80%的資源,我們優(yōu)化的重點是這些慢的地方。
24、假如使用了IN或者者OR等時發(fā)現(xiàn)查詢沒有走索引,使用顯示申明指定索引:
SELECT*FROMPersonMember(INDEX=IX_Title)WHEREprocessidIN('男','女')
25、將需要查詢的結(jié)果預(yù)先計算好放在表中,查詢的時候再SELECT。這在SQL7.0往常是
最重要的手段。比如醫(yī)院的住院費計算。
26、MIN()與MAX()能使用到合適的索引。
27、數(shù)據(jù)庫有一個原則是代碼離數(shù)據(jù)越近越好,因此優(yōu)先選擇Default,依次為Rules,Triggers,
Constraint(約束如外健主健CheckUNIQUE……,數(shù)據(jù)類型的最大長度等等都是約
束),Procedure.這樣不僅保護工作小,編寫程序質(zhì)量高,同時執(zhí)行的速度快。
28、假如要插入大的二進制值到Image歹U,使用存儲過程,千萬不要用內(nèi)嵌INsert來插入(不
知JAVA是否)。由于這樣應(yīng)用程序首先將二進制值轉(zhuǎn)換成字符串(尺寸是它的兩倍),服務(wù)
器受到字符后又將他轉(zhuǎn)換成二進制值.存儲過程就沒有這些動作:方法:
Createprocedurep_insertasinsertintotable(Fimage)values(@image)
在前臺調(diào)用這個存儲過程傳入二進制參數(shù),這樣處理速度明顯改善。
29、Between在某些時候比IN速度更快,Between能夠更快地根據(jù)索引找到范圍。用查詢優(yōu)
化器可見到差別。
select*fromchineseresumewheretitlein('男女')
Select*fromchineseresumewheretitlebetween'男’and'女’
是一樣的。由于in會在比較多次,因此有的時候會慢些。
30、在必要是對全局或者者局部臨時表創(chuàng)建索引,有的時候能夠提高速度,但不是一定會這
樣,由于索引也耗費大量的資源。他的創(chuàng)建同是實際表一樣。
31、不要建沒有作用的事物比如產(chǎn)生報表時,浪費資源。只有在必要使用事物時使用它。
32、用OR的字句能夠分解成多個查詢,同時通過UNION連接多個查詢。他們的速度只同
是否使用索引有關(guān),假如查詢需要用到聯(lián)合索引,用UNIONall執(zhí)行的效率更高.多個OR的
字句沒有用到索引,改寫成UNION的形式再試圖與索引匹配。一個關(guān)鍵的問題是否用到索
引。
33、盡量少用視圖,它的效率低。對視圖操作比直接對表操作慢,能夠用storedprocedure來
代替她。特別的是不要用視圖嵌套,嵌套視圖增加了尋找原始資料的難度。我們看視圖的本
質(zhì):它是存放在服務(wù)器上的被優(yōu)化好了的已經(jīng)產(chǎn)生了查詢規(guī)劃的SQL。對單個表檢索數(shù)據(jù)
時,不要使用指向多個表的視圖,直接從表檢索或者者僅僅包含這個表的視圖上讀,否則增
加了不必要的開銷,查詢受到干擾.為了加快視圖的查詢,MsSQL增加了視圖索引的功能。
34、沒有必要時不要用DISTINCT與ORDERBY,這些動作能夠改在客戶端執(zhí)行。它們增
加了額外的開銷。這同UNION與UNIONALL一樣的道理。
convert(varchar(10),ad.postDate,120)aspostDate1,workyear,degreedescriptionFROM
'JCNAD00333138','JCNAD00303570','JCNAD00303569',
,JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933,,
'JCNAD00254567','JCNAD00254585';JCNAD00254608,,
'JCNAD00254607','JCNAD00258524';JCNAD00332133','JCNAD00268618,,
'JCNAD00279196','JCNAD00268613')orderbypostdatedesc
35、在IN后面值的列表中,將出現(xiàn)最頻繁的值放在最前面,出現(xiàn)得最少的放在最后面,減
少推斷的次數(shù)。
36、當(dāng)用SELECTINTO時,它會鎖住系統(tǒng)表(sysobjects,sysindexes等等),堵塞其他的連
接的存取。創(chuàng)建臨時表時用顯示申明語句,而不是
selectINTO,droptablet_lxhbegintranselect*intot_lxhfromchineseresume
wherename='XYZ'—commit
在另一個連接中SELECT*fromsysobjects能夠看到SELECTINTO會鎖住系統(tǒng)表,Create
table也會鎖系統(tǒng)表(不管是臨時表還是系統(tǒng)表)。因此千萬不要在事物內(nèi)使用它!”這樣的
話假如是經(jīng)常要用的臨時表請使用實表,或者者臨時表變量。
37、通常在GROUPBY個HAVING字句之前就能剔除多余的行,因此盡量不要用它們來做
剔除行的工作。他們的執(zhí)行順序應(yīng)該如下最優(yōu):select的Where字句選擇所有合適的行,
GroupBy用來分組個統(tǒng)計行,Having字句用來剔除多余的分組。這樣GroupBy個Having
的開銷小,查詢快.關(guān)于大的數(shù)據(jù)行進行分組與Having十分消耗資源。假如GroupBY的目
的不包含計算,只是分組,那么用Distinct更快
38、一次更新多條記錄比分多次更新每次一條快,就是說批處理好
39、少用臨時表,盡量用結(jié)果集與Table類性的變量來代替它,Table類型的變量比臨時表好
40、在SQL2000下,計算字段是能夠索引的,需要滿足的條件如下:
a、計算字段的表達是確定的
b、不能用在TEXT,Ntext,Image數(shù)據(jù)類型
c、務(wù)必配制如下選項ANS1_NULLS=ON,ANSI_PADDINGS=ON,.
41、盡量將數(shù)據(jù)的處理工作放在服務(wù)器上,減少網(wǎng)絡(luò)的開銷,如使用存儲過程。存儲過程是
編譯好、優(yōu)化過、同時被組織到一個執(zhí)行規(guī)劃里、且存儲在數(shù)據(jù)庫中的SQL語句,是操縱
流語言的集合,速度當(dāng)然快。反復(fù)執(zhí)行的動態(tài)SQL,能夠使用臨時存儲過程,該過程(臨時
表)被放在Tempdb中。往常由于SQLSERVER對復(fù)雜的數(shù)學(xué)計算不支持,因此不得不將
這個工作放在其他的層上而增加網(wǎng)絡(luò)的開銷。SQL2000支持UDFs,現(xiàn)在支持復(fù)雜的數(shù)學(xué)計
算,函數(shù)的返回值不要太大,這樣的開銷很大。用戶自定義函數(shù)象光標(biāo)一樣執(zhí)行的消耗大量
的資源,假如返回大的結(jié)果使用存儲過程
42、不要在一句話里再三的使用相同的函數(shù),浪費資源,將結(jié)果放在變量里再調(diào)用更快
43、SELECTCOUNT(*)的效率教低,盡量變通他的寫法,而EXISTS快.同時請注意區(qū)別:
selectcount(Fieldofnull)fromTable與selectcount(FieldofNOTnull)fromTable的返回值
是不一致的?。?!
44、當(dāng)服務(wù)器的內(nèi)存夠多時,配制線程數(shù)量=最大連接數(shù)+5,這樣能發(fā)揮最大的效率;否
則使用配制線程數(shù)量〈最大連接數(shù)啟用SQLSERVER的線程池來解決,假如還是數(shù)量=最
大連接數(shù)+5,嚴(yán)重的損害服務(wù)器的性能。
45、按照一定的次序來訪問你的表。假如你先鎖住表A,再鎖住表B,那么在所有的存儲過
程中都要按照這個順序來鎖定它們。假如你(不經(jīng)意的)某個存儲過程中先鎖定表B,再鎖
定表A,這可能就會導(dǎo)致一個死鎖。假如鎖定順序沒有被預(yù)先全面的設(shè)計好,死鎖很難被發(fā)
現(xiàn)
46、通過SQLServerPerformanceMonitor監(jiān)視相應(yīng)硬件的負(fù)載Memory:PageFaults/sec計
數(shù)器假如該值偶爾走高,說明當(dāng)時有線程競爭內(nèi)存。假如持續(xù)很高,則內(nèi)存可能是瓶頸。
Process:
1、%DPCTime指在范例間隔期間處理器用在緩延程序調(diào)用(DPC)接收與提供服務(wù)的百分
比。(DPC正在運行的為比標(biāo)準(zhǔn)間隔優(yōu)先權(quán)低的間隔)。由于DPC是以特權(quán)模式執(zhí)行的,
DPC時間的百分比為特權(quán)時間百分比的一部分。這些時間單獨計算同時不屬于間隔計算總
數(shù)的一部分。這個總數(shù)顯示了作為實例時間百分比的平均忙時。
2、%ProcessorTime計數(shù)器假如該參數(shù)值持續(xù)超過95%,說明瓶頸是CPU。能夠考慮增加
一個處理器或者換一個更快的處理器。
3、%PrivilegedTime指非閑置處理器時間用于特權(quán)模式的百分比。(特權(quán)模式是為操作系統(tǒng)
組件與操縱硬件驅(qū)動程序而設(shè)計的一種處理模式。它同意直接訪問硬件與所有內(nèi)存。另一種
模式為用戶模式,它是一種為應(yīng)用程序、環(huán)境分系統(tǒng)與整數(shù)分系統(tǒng)設(shè)計的一種有限處理模式。
操作系統(tǒng)將應(yīng)用程序線程轉(zhuǎn)換成特權(quán)模式以訪問操作系統(tǒng)服務(wù))。特權(quán)時間的%包含為間
斷與DPC提供服務(wù)的時間。特權(quán)時間比率高可能是由于失敗設(shè)備產(chǎn)生的大數(shù)量的間隔而引
起的。這個計數(shù)器將平均忙時作為樣本時間的一部分顯示。
4、%UserTime表示耗費CPU的數(shù)據(jù)庫操作,如排序,執(zhí)行aggregatefunctions等。假如該
值很高,可考慮增加索引,盡量使用簡單的表聯(lián)接,水平分割大表格等方法來降低該值。
PhysicalDisk:CurretnDiskQueueLength計數(shù)器該值應(yīng)不超過磁盤數(shù)的1.5~2倍。要提高性
能,可增加磁盤。SQLServer:CacheHilRatio計數(shù)器該值越高越好。假如持續(xù)低于80%,
應(yīng)考慮增加內(nèi)存。注意該參數(shù)值是從SQLServer啟動后,就一直累加記數(shù),因此運行通過
一段時間后,該值將不能反映系統(tǒng)當(dāng)前值。
47、分析selectemp_nameformemployeewheresalary>3000在此語句中若salary是Float
類型的,則優(yōu)化器對其進行優(yōu)化為Convert(float,3000),由于3000是個整數(shù),我們應(yīng)在編程
時使用3000.0而不要等運行時讓DBMS進行轉(zhuǎn)化。同樣字符與整型數(shù)據(jù)的轉(zhuǎn)換。
48、查詢的關(guān)聯(lián)同寫的順序
selecta.personMemberlD,*fromchineseresumea,personmcmberbwherepersonMemberlD
=b.referenceidanda.personMemberlD='JCNPRH39681'(A=B,B='號碼')
selecta.personMemberlD,*fromchineseresumea,personmemberbwherea.personMemberlD
=b.referenceidanda.personMemberlD='JCNPRH39681'andb.referenceid='JCNPRH39681,
(八=82='號碼',人='號碼')
selecta.personMemberlD,*fromchineseresumea,personmemberbwhereb.referenceid
='JCNPRH39681'anda.personMemberlD='JCNPRH39681'(B=號碼',A='號碼')
49、
(1)1F沒有輸入負(fù)責(zé)人代碼THENcodel=0code2=9999ELSEcodel=code2=負(fù)責(zé)人代碼
ENDIF執(zhí)行SQL語句為:SELECT負(fù)責(zé)人名FROMP2000WHERE負(fù)責(zé)人代碼>=:codel
AND負(fù)責(zé)人代碼<=:code2
⑵IF沒有輸入負(fù)責(zé)人代碼THENSELECT負(fù)責(zé)人名FROMP2000ELSEcode=負(fù)責(zé)人代
碼SELECT負(fù)責(zé)人代碼FROMP2000WHERE負(fù)責(zé)人代碼=:codeENDIF第一種方法只
用了一條SQL語句,第二種方法用了兩條SQL語句。在沒有輸入負(fù)責(zé)人代碼時,第二種方法
顯然比第一種方法執(zhí)行效率高,由于它沒有限制條件;在輸入了負(fù)責(zé)人代碼時,第二種方法仍
然比第一種方法效率高,不僅是少了一個限制條件,還因相等運算是最快的查詢運算。我們寫
程序不要怕煩惱
50、關(guān)于JOBCN現(xiàn)在查詢分頁的新方法(如下),用性能優(yōu)化器分析性能的瓶頸,假如在
I/O或者者網(wǎng)絡(luò)的速度上,如下的方法優(yōu)化切實有效,假如在CPU或者者內(nèi)存上,用現(xiàn)在的
方法更好。請區(qū)分如下的方法,說明索引越小越好。
begin
DECLARE@local_variabletable(FIDintidenlily(1,1),ReferenceIDvarchar(20))
insertinto@local_variable(ReferencelD)
selecttop100000ReferencelDfromchineseresumeorderbyReferencelD
select*from@local_variablewhereFid>40andfid<=60
end
與
begin
DECLARE@local_variabletable(FIDintidentity(1,1),ReferenceIDvarchar(20))
insertinto@local_variable(ReferencelD)
selecttop100000ReferencelDfromchineseresumeorderbyupdatedate
select*from@local_variablewhereFid>40andfid<=60
end
的不一致
begin
createtable#temp(FIDintidentity(1,1),ReferencelDvarchar(20))
insertinto#temp(ReferencelD)
selecttop100000ReferencelDfromchineseresumeorderbyupdatedate
select*from#tempwhereFid>40andfid<=60droptable#temp
end
數(shù)據(jù)庫性能調(diào)優(yōu)技術(shù)-索引調(diào)優(yōu)
一、概述
隨著數(shù)據(jù)庫在各個領(lǐng)域的使用不斷增長,越來越多的應(yīng)用提出了高性能的要求。數(shù)據(jù)庫性
能調(diào)優(yōu)是知識密集型的學(xué)科,需要綜合考慮各類復(fù)雜的因素:數(shù)據(jù)庫緩沖區(qū)的大小、索引的
創(chuàng)建、語句改寫等等。總之,數(shù)據(jù)庫性能調(diào)優(yōu)的目的在于使系統(tǒng)運行得更快。
調(diào)優(yōu)需要有廣泛的知識,這使得它既簡單又復(fù)雜。
說調(diào)優(yōu)簡單,是由于調(diào)優(yōu)者不必糾纏于復(fù)雜的公式與規(guī)則。許多學(xué)術(shù)界與業(yè)界的研究者都在
嘗試將調(diào)優(yōu)與查詢處理建立在數(shù)學(xué)基礎(chǔ)之上。
稱調(diào)優(yōu)復(fù)雜,是由于假如要完全懂得常識所依靠的原理,還需要對應(yīng)用、數(shù)據(jù)庫管理系統(tǒng)、
操作系統(tǒng)與硬件有廣泛而深刻的懂得。
數(shù)據(jù)庫調(diào)優(yōu)技術(shù)能夠在不一致的數(shù)據(jù)庫系統(tǒng)中使用。假如需要調(diào)優(yōu)數(shù)據(jù)庫系統(tǒng),最好掌握如
下知識:1)查詢處理、并發(fā)操縱與數(shù)據(jù)庫恢復(fù)的知識;2)一些調(diào)優(yōu)的基本原則。
這里要緊描述索引調(diào)優(yōu)。
二、索引調(diào)優(yōu)
索引是建立在表上的一種數(shù)據(jù)組織,它能提高訪問表中一條或者多條記錄的特定查詢效
率。因此,適當(dāng)?shù)乃饕{(diào)優(yōu)是很重要的。
關(guān)于索引調(diào)優(yōu)存在如下的幾個誤區(qū):
誤區(qū)1:索引創(chuàng)建得越多越好?
實際上:創(chuàng)建的索引可能建立后從來未使用。索引的創(chuàng)建也是需要代價的,關(guān)于刪除、
某些更新、插入操作,關(guān)于每個索引都要進行相應(yīng)的刪除、更新、插入操作。從而導(dǎo)致刪除、
某些更新、插入操作的效率變低。
誤區(qū)2:關(guān)于一個單表的查詢,能夠索引1進行過濾再使用索引2進行過濾?
實際上:假設(shè)查詢語句如下select*fromtlwherec1=1andc2=2,cl列與c2列上分別建
有索引icl、ic2。先使用icl(或者ic2)進行過濾,產(chǎn)生的結(jié)果集是臨時數(shù)據(jù),不再具有索引,
因此不可使用ic2(或者icl)進行再次過濾。
索引優(yōu)化的基本原則:
1.將索引與數(shù)據(jù)存放到不一致的文件組
沒有將表數(shù)據(jù)與索引數(shù)據(jù)存儲到不一致的文件組,而不加區(qū)別地將它們存儲到同一文件
組。這樣,不但會造成I/O競爭,也為數(shù)據(jù)庫的保護工作帶來不變。
2.組合索引的使用
假設(shè)存在組合索引itlclc2(cl,c2),查詢語句select*fromtlwherecI=1andc2=2能夠使用
該索引。查詢語句select*fromtlwherecl=l也能夠使用該索引。但是,查詢語句select*from
tlwherec2=2不能夠使用該索引,由于沒有組合索引的引導(dǎo)列,即,要想使用c2列進行查
找,必需出現(xiàn)cl等于某值。
根據(jù)where條件的不一致,歸納如下:
l)cl=landc2=2:使用索引itlclc2進行等值查找。
2)cl=landc2>2:使用索引itlclc2進行范圍查找,能夠有兩種方法。
方法1,使用通過索引鍵(1,2)在B樹中命中一條記錄,然后向后掃描找出第一條符
合條件的記錄,從此記錄往后的每一條記錄都是符合條件的。這種方法的弊端在于:假如
cl=landc2=2對應(yīng)的記錄數(shù)很多,會產(chǎn)生很多無效的掃描。
方法2,假如c2對應(yīng)的int型數(shù)據(jù),能夠使用索引鍵(1,3)在B樹中命中一條記錄,從此記
錄往后的每一條記錄都是符合條件的。
本文中的例子均使用方法1?
3)cl>landc2=2:由于索引的第一個列不是等于號的,索引即使后面出現(xiàn)了c2=2,也不能
將c2=2應(yīng)用于索引查找。這里,通過索引鍵(1,-8)在B樹中命中一條記錄,向后掃描找出
第一條符合cl>l的記錄,此后的每一條記錄推斷是否符合c2=2,假如符合則輸出,否則過
濾掉。這里我們稱c2=2沒有參與到索引運算中去。這種情況在實際應(yīng)用中經(jīng)常出現(xiàn)。
4)cl>l:通過索引鍵(1,-8)在B樹中命中一條記錄,以此向后掃描找出第一條符合cl>l
的記錄,此后的每條記錄都是符合條件的。
3.唯一索引與非唯一索引的差異
假設(shè)索引intlcl(cl)是唯一索引,關(guān)于查詢語句selectclfromtlwherecl=l,達夢數(shù)據(jù)庫
使用索引鍵(1)命中B樹中一條記錄,命中之后直接返回該記錄(由因此唯一索引,因此最
多只能有一條cl=l的記錄)。
假設(shè)索引itlc2(c2)是非唯一索引,關(guān)于查詢語句selectc2fromt2wherec2=2,達夢數(shù)據(jù)
庫使用索引鍵(2)命中B樹中一條記錄,返回該記錄,并繼續(xù)向后掃描,假如該記錄是滿足
c=2,返回該記錄,繼續(xù)掃描,直到遇到第一條不符合條件c2=2的記錄。
因此,我們能夠得知,關(guān)于不存在重復(fù)值的列,創(chuàng)建唯一索引優(yōu)于創(chuàng)建非唯一索引。
4.非聚集索引的作用
每張表只可能一個聚集索引,聚集索引用來組織真實數(shù)據(jù)。語句“createtableemployee(id
intclusterprimarykey,namevarchar(20),addrvarcharQO))"。表employee的數(shù)據(jù)用id來組織。
假如要查找id=1000的員工記錄,只要用索引鍵(1000)命中該聚集索引。但是,關(guān)于要查
找name='張三'的員工記錄就不能使用該索引了,需要進行全表掃描,關(guān)于每一條記錄推
斷是否滿足name='張三',這樣會導(dǎo)致查詢效率非常低。
要使用聚集索弓I,必需提供id,我們只能提供name,因此需要引入一個輔助結(jié)構(gòu)實現(xiàn)name
到id的轉(zhuǎn)換,這就是非聚集索引的作用。該非聚集索引的鍵是name,值是id。因此語句“select
*fromemployeewherename=>張三的執(zhí)行流程是:通過鍵('張三’)命中非聚集索引,
得到對應(yīng)的id值3(假設(shè)‘張三'對應(yīng)的id為3),然后用鍵(3)命中聚集索引,得到相應(yīng)的
記錄。
5.是不是使用非聚集索引的查詢都需要進行聚集的查詢?
不是的,盡管在上一點中查詢轉(zhuǎn)換為聚集索引的查找,有的時候候能夠只需要使用非聚
集索引。
創(chuàng)建表并創(chuàng)建相應(yīng)的索引:createtabletl(clint,c2int,c3int);createindexitlc2c3on
tl(c2,c3)o查詢語句為:selectc3from11wherec2=1?
由于索引itlc2c3(c2,c3)覆蓋查詢語句中的列(c2,c3).因此,該查詢語句的執(zhí)行流程為:通過
索引鍵(1,-8)命中索引itk2c3,關(guān)于該記錄直接返回c3對應(yīng)的值,繼續(xù)向后掃描,假如索
引記錄中cl還是等于1,那么輸出c3,以此類推,直到出現(xiàn)第一條cl不等于1的索引記錄,
結(jié)束查詢。
6.創(chuàng)建索引的規(guī)則
創(chuàng)建索引首先要考慮的是列的可選擇性。比較一下列中唯一鍵的數(shù)量與表中記錄的行數(shù),
就能夠推斷該列的可選擇性。假如該列的“唯一鍵的數(shù)量/表中記錄行數(shù)”的比值越接近于1,
則該列的可選擇行越高。在可選擇性高的列上進行查詢,返回的數(shù)據(jù)就較少,比較適合索引
查詢。相反,比如性別列上只有兩個值,可選擇行就很小,不適合索引查詢。
SQLServer中調(diào)整自增字段的當(dāng)前初始值
前幾天在把一個CommuntiyServer的數(shù)據(jù)庫從SQL2000升級到SQL2005的時候,碰到一
個怪異的問題,報如下錯誤:
ViolationofPRIMARYKEYconstraint'PK_cs_Threads'.Cannotinsertduplicatekeyinobject
'dbo.cs_Threads'.
分析進去后,居然發(fā)現(xiàn)這個表的自增字段數(shù)據(jù)庫中已經(jīng)達到了6144,而數(shù)據(jù)庫保護的這個
表的初始自增值只到6109。
解決方法很簡單,利用下列SQL語句即可搞定:
DBCCCHECKIDENT('cs_Threads')
上述語句的意思就是:假如表'cs_Threads的當(dāng)前標(biāo)識值小于列中存儲的最大標(biāo)識值,則使用
標(biāo)識列中的最大值對其進行重置。
CHECKIDENT命令能夠有下列幾種寫法:
1、DBCCCHECKIDENT('table_name',NORESEED)
不重置當(dāng)前標(biāo)識值。DBCCCHECKIDENT返回一個報表,它指明當(dāng)前標(biāo)識值與應(yīng)有的標(biāo)識
值。
類似如下的報表:
Checkingidentityinformation:currentidentityvalue'6109',currentcolumnvalue'6144'.
2、DBCCCHECKIDENT('table_name')或者DBCCCHECKIDENT('table_name',RESEED)
假如表的當(dāng)前標(biāo)識值小于列中存儲的最大標(biāo)識值,則使用標(biāo)識列中的最大值對其進行重置。
上述命令執(zhí)行的時候,也會報類似上面的報表。
3、DBCCCHECKIDENT('table_name',RESEED,new_reseed_value)
當(dāng)前值設(shè)置為new_reseed_value。
假如自創(chuàng)建表后沒有將行插入該表,則在執(zhí)行DBCCCHECKIDENT后插入的第一行將使
用new_reseed_value作為標(biāo)識。否則,下一個插入的行將使用new_reseed_value+1o
假如new_reseed_value的值小于標(biāo)識列中的最大值,以后引用該表時將產(chǎn)生2627號錯誤
信息。
使用時容易忽略SQLServer的21個問題
假如你正在負(fù)責(zé)一個基于SQLServer的項目,或者者你剛剛接觸SQLServer,你都有可能
要面臨一些數(shù)據(jù)庫性能的問題,這篇文章會為你提供一些有用的指導(dǎo)(其中大多數(shù)也能夠用
于其它的DBMS)。
在這里,我不打算介紹使用SQLServer的竅門,也不能提供一個包治百病的方案,我
所做的是總結(jié)一些經(jīng)驗--關(guān)于如何形成一個好的設(shè)計。這些經(jīng)驗來自我過去幾年中經(jīng)受的
教訓(xùn),一直來,我看到許多同樣的設(shè)計錯誤被一次又一次的重復(fù)。
你熟悉工具嗎?
不要輕視這一點,這是我在這篇文章中講述的最關(guān)鍵的一條。也許你也看到有很多的
SQLServer程序員沒有掌握全部的T-SQL命令與SQLServer提供的那些有用的工具。
“什么?我要浪費一個月的時間來學(xué)習(xí)那些我永遠也不可能用到的SQL命令???”,
你也許會這樣說。對的,你不需要這樣做。但是你應(yīng)該用一個周末瀏覽所有的T-SQL命令。
在這里,你的任務(wù)是熟悉,將來,當(dāng)你設(shè)計一個查詢時,你會記起來:“對了,這里有一個
命令能夠完全實現(xiàn)我需要的功能”,因此,到MSDN查看這個命令的確切語法。
不要使用光標(biāo)
讓我再重復(fù)一遍:不要使用光標(biāo)。假如你想破壞整個系統(tǒng)的性能的話,它們倒是你最有
效的首選辦法。大多數(shù)的初學(xué)者都使用光標(biāo),而沒有意識到它們對性能造成的影響。它們占
用內(nèi)存,還用它們那些不可思議的方式鎖定表,另外,它們簡直就像蝸牛。而最糟糕的是,
它們能夠使你的DBA所能做的一切性能優(yōu)化等于沒做。不知你是否明白每執(zhí)行一次FETCH
就等于執(zhí)行一次SELECT命令?這意味著假如你的光標(biāo)有10000條記錄,它將執(zhí)行10000
次SELECT!假如你使用一組SELECT、UPDATE或者者DELETE來完成相應(yīng)的工作,那
將有效率的多。
初學(xué)者通常認(rèn)為使用光標(biāo)是一種比較熟悉與舒適的編程方式,可很不幸,這會導(dǎo)致糟糕
的性能。顯然,SQL的總體目的是你要實現(xiàn)什么,而不是如何實現(xiàn)。
我曾經(jīng)用T-SQL重寫了一個基于光標(biāo)的存儲過程,那個表只有100,000條記錄,原先的
存儲過程用了40分鐘才執(zhí)行完畢,而新的存儲過程只用了10秒鐘。在這里,我想你應(yīng)該能
夠看到一個不稱職的程序員畢竟在干了什么!!!
我們能夠?qū)懸粋€小程序來取得與處理數(shù)據(jù)同時更新數(shù)據(jù)庫,這樣做有的時候會更有效。
記住:關(guān)于循環(huán),T-SQL無能為力。
我再重新提醒一下:使用光標(biāo)沒有好處。除了DBA的工作外,我從來沒有看到過使用
光標(biāo)能夠有效的完成任何工作。
規(guī)范化你的資料表
為什么不規(guī)范化數(shù)據(jù)庫?大概有兩個借口:出于性能的考慮與純粹由于懶惰。至于第二
點,你遲早得為此付出代價。而關(guān)于性能的問題,你不需要優(yōu)化根本就不慢的東西。我經(jīng)常
看到一些程序員“反規(guī)范化”數(shù)據(jù)庫,他們的理由是“原先的設(shè)計太慢了”,可結(jié)果卻常常
是他們讓系統(tǒng)更慢了。DBMS被設(shè)計用來處理規(guī)范數(shù)據(jù)庫的,因此,記?。喊凑找?guī)范化的
要求設(shè)計數(shù)據(jù)庫。
不要使用SELECT*
這點不太容易做到,我太熟悉了,由于我自己就經(jīng)常這樣干。但是,假如在SELECT
中指定你所需要的列,那將會帶來下列的好處:
1減少內(nèi)存耗費與網(wǎng)絡(luò)的帶寬
2你能夠得到更安全的設(shè)計
3給查詢優(yōu)化器機會從索引讀取所有需要的列
熟悉你將要對數(shù)據(jù)進行的操作
為你的數(shù)據(jù)庫創(chuàng)建一個健壯的索引,那但是功德一件??梢龅竭@一點簡直就是一門藝
術(shù)。每當(dāng)你為一個表添加一個索引,SELECT會更快了,可INSERT與DELETE去[1大大的
變慢了,由于創(chuàng)建了保護索引需要許多額外的工作。顯然,這里問題的關(guān)鍵是:你要對這張
表進行什么樣的操作。這個問題不太好把握,特別是涉及DELETE與
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 吉林工業(yè)職業(yè)技術(shù)學(xué)院《文化與翻譯》2023-2024學(xué)年第二學(xué)期期末試卷
- 上海農(nóng)林職業(yè)技術(shù)學(xué)院《大數(shù)據(jù)技術(shù)概論》2023-2024學(xué)年第二學(xué)期期末試卷
- 常州工學(xué)院《中小學(xué)管理學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 泰州2025年江蘇泰州市第二人民醫(yī)院招聘衛(wèi)生專業(yè)技術(shù)人員21人筆試歷年參考題庫附帶答案詳解-1
- 2025年熱壓硫化鋅(ZNS)晶體合作協(xié)議書
- 溫州大學(xué)《結(jié)構(gòu)力學(xué)上》2023-2024學(xué)年第二學(xué)期期末試卷
- 泉州輕工職業(yè)學(xué)院《微生物資源開發(fā)與利用》2023-2024學(xué)年第二學(xué)期期末試卷
- 清遠職業(yè)技術(shù)學(xué)院《學(xué)校心理學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 重慶商務(wù)職業(yè)學(xué)院《數(shù)據(jù)新聞與數(shù)據(jù)可視化》2023-2024學(xué)年第二學(xué)期期末試卷
- 福建信息職業(yè)技術(shù)學(xué)院《海商法學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024年春學(xué)期人教版pep版小學(xué)英語五年級下冊教學(xué)進度表
- 2024年知識競賽-《民用爆炸物品安全管理條例》知識競賽筆試參考題庫含答案
- 出師表(選擇題)答案版
- (正式版)JBT 9229-2024 剪叉式升降工作平臺
- (高清版)DZT 0208-2020 礦產(chǎn)地質(zhì)勘查規(guī)范 金屬砂礦類
- (高清版)DZT 0368-2021 巖礦石標(biāo)本物性測量技術(shù)規(guī)程
- 礦山開采與環(huán)境保護
- 企業(yè)事業(yè)部制的管理與監(jiān)督機制
- 兒童體液平衡及液體療法課件
- 勞動防護用品培訓(xùn)試卷帶答案
- ORACLE執(zhí)行計劃和SQL調(diào)優(yōu)
評論
0/150
提交評論