sybase性能优化经验浅谈
http://www.2cto.com/database/201204/129094.html
使用sybase數據庫多年,有些經驗,在數據庫部署配置得當,平時監控維護做到位情況下,除此之外數據庫的性能問題80%將會是由sql語句引起。
經驗一、where 條件左邊最好不要使用函數,比如: select ...???? where???? datediff(day,date_column,getdate())>0 這樣即使在date_column列上建立了索引,也可能不會使用索引,而使用全表掃描。 這樣的語句要重新規劃設計,保證不使用函數也能夠實現。通過修改,一個系統過程的運行效率提高大約幾十倍甚至上百倍!此外不要使用諸如like '%ab',不能充分利用索引,而要在%前加字符。
經驗二、兩個比較字段最好使用相同數據類型,而不是兼容數據類型。比如 int 與 numeric(感覺一般不是太明顯)。? www.2cto.com?
經驗三、復合索引的非前導列做條件時,基本沒有起到索引的作用。 比如 create index idx_tablename_ab on tablename(a,b) update tablename set c = XX where b>= XXX and ... 在這個語句中,只用了索引列b而沒用索引列a做查詢條件,基本上索引沒有發揮作用。 導致表掃描引起blocking 甚至運行十幾分鐘后報告失敗。 一定要認真檢查 改正措施: 在接口中附加條件 update tablename set c = XX? where? a = XXX? and b>= XXX 或者建立索引類似于 create index idx_tablename_ba on tablename(b,a)
經驗四、 多個大表的關聯查詢,如果性能不好,并且其中一個大表中取的數據比較少,可以考慮將查詢分兩步執行。 先將一個大表中的少部分數據 select * into #tmp from large_table where ... 然后再用 #tmp 去做關聯,效果可能會好不少。(前提:生成 #tmp表時,訪問large_table 用到了比較好的索引,速度比較快)
經驗五、 tempdb 的使用。 最好多用 select? into ,這樣不記日志 ,尤其是有大量數據的報表時。雖然寫起來麻煩,但值得。 create table #tmp (......)這樣寫性能不好。尤其是大量使用時,容易發生tempdb 爭用。
經驗六、 系統級別的參數設置???? 一定要估計一下,不要配置太多,占用資源 ,配置太少,發生性能問題。 連接數,索引打開個數、鎖個數 等、 當然 ,內存配置不要有明顯的問題,比如,procedure cache 不夠 (一般缺省20%,如果覺得太多,可以減少一些)。如果做報表經常使用大數據量讀,可以考慮使用? www.2cto.com?? 16K data cache
經驗七、索引的建立,很重要。 clustered index???? /nonclustered index 的差異,自己要搞清楚。各適用場合,另外如果 clustered index 不允許 重復數,也一定要說明。 索引設計是以為數據訪問快速為原則的,不能 完全參照數據邏輯設計的,邏輯設計時的一些東西,可能對物理訪問不起作用 經驗八、定期統計量數據的更新,更新頻率看數據變化速度,一般數據發生10-15%左右變化就要進行統計量的更新,否則索引容易失效,update statistics
經驗九、定期
經驗九、強制索引使用 如果懷疑有表訪問時不是使用索引,而且這些條件字段上建立了合適的索引,可以強制使用 select * from tableA (index idx_name) where ... 這個對一些報表程序可能比較有用。
經驗十、找一個好的監視工具 工欲善其事,必先利其器,一點都不錯呀。 我用 DBArtisan ,監視哪些表被鎖定時間長, blocking 等 還有 sp_object_status 20:00:00 , sp_sysmon 20:00:00 等
經驗十一: 綜合以上對IN/EXISTS的討論,我們可以得出一個基本通用的結論:IN適合于外表大而內表小的情況;EXISTS適合于外表小而內表大的情況。 另外,系統中確認不使用的中間數據,可以進行轉移。這些要看系統的情況哦 最后祝你好運氣。? www.2cto.com? 以上為個人經驗,歡迎批評指正!???? 呵呵 寫完后忘記一個???? 一定要注意熱點表 ,這是影響并發問題的一個潛在因素!
解決方法: 行鎖模式 如果表的行比較小,可以故意增加一些不用的字段 比如???? char(200)???? 讓一頁中存放的行不要太多。 Sybase 索引的使用和優化詳解 ================================= http://database.9sssd.com/sybase/art/537
[摘要]采用索引來加快數據處理速度成為廣大數據庫用戶所接受的優化方法,本文介紹Sybase 索引的使用和優化。
在應用系統中,尤其在聯機事務處理系統中,對數據查詢及處理速度已成為衡量應用系統成敗的標準。而采用索引來加快數據處理速度也成為廣大數據庫用戶所接受的優化方法。在良好的數據庫設計基礎上,能有效地使用索引是SQLServer取得高性能的基礎,SQLServer采用基于代價的優化模型,它對每一個提交的有關表的查詢,決定是否使用索引或用哪一個索引。因為查詢執行的大部分開銷是磁盤I/O,使用索引提高性能的一個主要目標是避免全表掃描,因為全表掃描需要從磁盤上讀表的每一個數據頁,如果有索引指向數據值,則查詢只需讀幾次磁盤就可以了。所以如果建 立了合理的索引,優化器就能利用索引加速數據的查詢過程。但是,索引并不總是提高系統的性能,在增、刪、改操作中索引的存在會增加一定的工作量,因此,在適當的地方增加適當的索引并從不合理的地方刪除次優的索引,將有助于優化那些性能較差的SQLServer應用。實踐表明,合理的索引設計是建立在對各種查詢的分析和預測上的,只有正確地使索引與程序結合起來,才能產生最佳的優化方案。本文就SQLServer索引的性能問題進行了一些分析和實踐。
一、聚簇索引(clusteredindexes)的使用 聚簇索引是一種對磁盤上實際數據重新組織以按指定的一個或多個列的值排序。由于聚簇索引的索引頁面指針指向數據頁面,所以使用聚簇索引查找數據幾乎總是比使用非聚簇索引快。每張表只能建一個聚簇索引,并且建聚簇索引需要至少相當該表120%的附加空間,以存放該表的副本和索引中間頁。建立聚簇索引的思想 是:
1、大多數表都應該有聚簇索引或使用分區來降低對表尾頁的競爭,在一個高事務的環境中,對最后一頁的封鎖嚴重影響系統的吞吐量。
2、在聚簇索引下,數據在物理上按順序排在數據頁上,重復值也排在一起,因而在那些包含范圍檢查(between、<、<=、>、>=)或使用group by或order by的查詢時,一旦找到具有范圍中第一個鍵值的行,具有后續索引值的行保證物理上毗連在一起而不必進一步搜索,避免了大范圍掃描,可以大大提高查詢速度。
3、在一個頻繁發生插入操作的表上建立聚簇索引時,不要建在具有單調上升值的列(如IDENTITY)上,否則會經常引起封鎖沖突。
4、在聚簇索引中不要包含經常修改的列,因為碼值修改后,數據行必須移動到新的位置。
5、選擇聚簇索引應基于where子句和連接操作的類型。
聚簇索引的侯選列是:
- 主鍵列,該列在where子句中使用并且插入是隨機的。
- 按范圍存取的列,如pri_order> 100 and pri_order < 200 。
- 在group by或order by中使用的列。
- 不經常修改的列。
- 在連接操作中使用的列。
二、非聚簇索引(nonclusteredindexes)的使用 SQL Server缺省情況下建立的索引是非聚簇索引,由于非聚簇索引不重新組織表中的數據,而是對每一行存儲索引列值并用一個指針指向數據所在的頁面。換句話說非聚簇索引具有在索引結構和數據本身之間的一個額外級。一個表如果沒有聚簇索引時,可有250個非聚簇索引。每個非聚簇索引提供訪問數據的不同排序順 序。在建立非聚簇索引時,要權衡索引對查詢速度的加快與降低修改速度之間的利弊。另外,還要考慮這些問題:
- 索引需要使用多少空間。
- 合適的列是否穩定。
- 索引鍵是如何選擇的,掃描效果是否更佳。
- 是否有許多重復值。 對更新頻繁的表來說,表上的非聚簇索引比聚簇索引和根本沒有索引需要更多的額外開銷。移到新頁的每一行而言,指向該數據的每個非聚簇索引的頁級行也必須更新,有時可能還需要索引頁的分理。從一個頁面刪除數據的進程也會有類似的開銷,另外,刪除進程還必須把數據移到頁面上部,以保證數據的連續性。所以,建立非聚簇索引要非常慎重。
非聚簇索引常被用在以下情況:
- 某列常用于集合函數(如Sum,....)。
- 某列常用于join,orderby,group by。
- 查尋出的數據不超過表中數據量的20%。
三、覆蓋索引(coveringindexes)的使用 覆蓋索引是指那些索引項中包含查尋所需要的全部信息的非聚簇索引,這種索引之所以比較快也正是因為索引頁中包含了查尋所必須的數據,不需去訪 問數據頁。如果非聚簇索引中包含結果數據,那么它的查詢速度將快于聚簇索引。但是由于覆蓋索引的索引項比較多,要占用比較大的空間。而且update操作會引起索引值改變。所以如果潛在的覆蓋查詢并不常用或不太關鍵,則覆蓋索引的增加反而會降低性能。
四、索引的選擇技術 p_detail是住房公積金管理系統中記錄個人明細的表,有890000行,觀察在不同索引下的查詢運行效果,測試在C/S環境下進行,客戶機是IBM PII350(內存64M),服務器是DECAlpha1000A(內存128M),數據庫為SYBASE11.0.3。
| 1 2 3 | select count(*) from p_detail where op_date>’19990101’ and op_date<’19991231’ and pri_surplus1>300 select count(*),sum(pri_surplus1) from p_detail where op_date>’19990101’ and pay_month between‘199908’ and ’199912’ |
不建任何索引 查詢1 1分15秒 查詢2 1分7秒
在op_date上建非聚簇索引 查詢1 57秒 查詢2 57秒
在op_date上建聚簇索引 查詢1 <1秒 查詢2 52秒
在pay_month、op_date、pri_surplus1上建索引 查詢1 34秒 查詢2 <1秒 在op_date、pay_month、pri_surplus1上建索引查詢1 <1秒 查詢2 <1秒 從以上查詢效果分析,索引的有無,建立方式的不同將會導致不同的查詢效果,選擇什么樣的索引基于用戶對數據的查詢條件,這些條件體現于where從句和 join表達式中。
一般來說建立索引的思路是:
(1)、主鍵時常作為where子句的條件,應在表的主鍵列上建立聚簇索引,尤其當經常用它作為連接的時候。
(2)、有大量重復值且經常有范圍查詢和排序、分組發生的列,或者非常頻繁地被訪問的列,可考慮建立聚簇索引。
(3)、經常同時存取多列,且每列都含有重復值可考慮建立復合索引來覆蓋一個或一組查詢,并把查詢引用最頻繁的列作為前導列,如果可能盡量使關鍵查詢形成覆蓋查詢。
(4)、如果知道索引鍵的所有值都是唯一的,那么確保把索引定義成唯一索引。
(5)、在一個經常做插入操作的表上建索引時,使用fillfactor(填充因子)來減少頁分裂,同時提高并發度降低死鎖的發生。如果在只讀表上建索引,則可以把fillfactor置為100。
(6)、在選擇索引鍵時,設法選擇那些采用小數據類型的列作為鍵以使每個索 引頁能夠容納盡可能多的索引鍵和指針,通過這種方式,可使一個查詢必須遍歷的索引頁面降到最小。此外,盡可能地使用整數為鍵值,因為它能夠提供比任何數據類型都快的訪問速度。
五、索引的維護 上面講到,某些不合適的索引影響到SQLServer的性能,隨著應用系統的運行,數據不斷地發生變化,當數據變化達到某一個程度時將 會影響到索引的使用。這時 需要用戶自己來維護索引。索引的維護包括: 1、重建索引 隨著數據行的插入、刪除和數據頁的分裂,有些索引頁可能只包含幾頁數據,另外應用在執行大塊I/O的時候,重建非聚簇索引可以降低分片,維護大塊I/O的效率。重建索引實際上是重新組織B-樹空間。在下面情況下需要重建索引:
(1)、數據和使用模式大幅度變化。
(2)、排序的順序發生改變。
(3)、要進行大量插入操作或已經完成。
(4)、使用大塊I/O的查詢的磁盤讀次數比預料的要多。
(5)、由于大量數據修改,使得數據頁和索引頁沒有充分使用而導致空間的使用超出估算。
(6)、dbcc檢查出索引有問題。 當重建聚簇索引時,這張表的所有非聚簇索引將被重建.
2、索引統計信息的更新 當在一個包含數據的表上創建索引的時候,SQLServer會創建分布數據頁來存放有關索引的兩種統計信息:分布表和密度表。優化器利用這個頁來判斷該索引對某個特定查詢是否有用。但這個統計信息并不動態地重新計算。這意味著,當表的數據改變之后,統計信息有可能是過時的,從而影響優化器追求最有工作的目標。因此,在下面情況下應該運行updatestatistics命令:
(1)、數據行的插入和刪除修改了數據的分布。
(2)、對用truncatetable刪除數據的表上增加數據行。
(3)、修改索引列的值。 六、結束語 實踐表明,不恰當的索引不但于事無補,反而會降低系統的執行性能。因為大量的索引在插入、修改和刪除操作時比沒有索引花費更多的系統時間。
例如下面情況下 建立的索引是不恰當的:
- 在查詢中很少或從不引用的列不會受益于索引,因為索引很少或從來不必搜索基于這些列的行。
- 只有兩個或三個值的列,如男性和女性(是或否),從不會從索引中得到好處。另外,鑒于索引加快了查詢速度,但減慢了數據更新速度的特點??赏ㄟ^在一個段上建表,而在另一個段上建其非聚簇索。
建立Clustered索引原則:
1、Primarykey,但必須滿足以下條件:A、常用于Where條件,B、插入記錄時的字段值是隨機的(不能用于順序增加的字段,否則將增加最后一個數據頁的lock等待時間)
2、用于范圍查詢的字段,如 col1 between 100 and 200; col12>;62 and <70;
3、用于orderby的字段
4、不經常改變(update)的字段
5、用于連接條件的字段
其他有關建立索引的原則:
1、如果索引是唯一的,將其定義為Unique
2、如果使用引用表索引(foreign key ... reference),被引用的列必須建立唯一索引
3、如果建立索引的表有頻繁的插入(Insert)操作,使用fillfactor減少數據頁的分裂、提高并發性能并減少死鎖
4、如果在一個只讀表上建立索引,將其fillfactor設為100以盡可能壓縮數據和索引空間
5、盡可能減少單個索引的長度
6、在滿足使用的前提下,盡可能使用小容量的數據類型(如用numeric代替char)
7、數值(numeric)的比較在內部操作上比字符(string)略快
8、變長字符串(varchar)和二進制(binary)類型比定長(fixed-length)類型需要更多的系統負載
9、只要可能,使用定長(fixed-length)、非空(non-null)、短(short)的數據類型字段作為索引
10、連接條件兩端的索引必須是兼容的(最好是同一類型),如果需要進行數據轉換的話,連接索引將不能發揮作用
建立復合字段索引的原則
1、當條件內不包含復合索引的第一個字段時,有兩種可能:A、當所有select的字段均包含在復合索引內時,做所有索引頁的遍歷查詢,B、當select中包含非復合索引字段時,做全表數據頁的遍歷查詢,既此時索引對檢索無效。
2、復合索引優點:A、提供索引覆蓋(index covering)的機會,但僅限于所有查詢(select)字段均包含在索引內,B、當查詢條件使用到復合索引的所有字段時,所需要時間少于這些字段建立單獨索引的情況,C、復合索引有利于強制多個屬性合并后的唯一性限制
3、復合索引缺點:A、需要更多的索引空間,減少每個索引頁包含的索引記錄數,并增加索引頁數目,B、對復合索引中任何一個字段的變化(update或insert)都會更新索引,因此復合索引必須選擇不進行變化的字段組成
4、差的復合索引特點:A、復合索引長度接近于記錄長度,B、復合索引中只有少量字段用于查詢
SYBASE建立索引的原則
補充一點:
--創建非聚集索引
1.滿足查詢條件的數據不超過20%
2.能實現 index covering
3.用于集函數、連接、group by和order by的列
4.要權衡索引對查詢速度的加快與降低修改速度之間的利弊
--刪除影響性能的索引
如果一個應用在白天執行數據修改,在夜間生成報表,就需要在早晨刪除索引,在晚上再把索引重建起來。
另外許多系統設計者創建許多優化器很少使用的索引,可以根據showplan,把沒有用的索引刪除。
建立索引
| 1 2 | create unique clustered index code1thidx1 on code_1th(Code1,Name,UnitNo1,Used) on segrun |
Unique: 建立唯一性索引
Clustered : 建立聚集索引,使得數據行的邏輯順序與物理順序一致,查詢速度較快;每個表僅允許建立一個唯一性索引。(非聚集索引nonclustered)
On segrun:將索引放在segrun上
x 刪除索引: dropindex code_1th.code1thidx1
一、APL表的索引
1、Clustering Index:
root level:only one page
intermediate level:
leaf level: leaf page就是數據頁(所以查詢計劃通過索引就可以讀數據)
2、Noclustering Index(heap table):leaf page存放數據頁的rowid(所以查詢計劃通過索引只能拿到key,再去讀數據)
二、DOL表的索引
Clustering Index和NonClustering index與在APL表上的非聚集索引結構一樣。(所以查詢計劃通過索引只能拿到key,再去讀數據)
索引提示:
1、索引失靈:
當使用>條件查詢返回的記錄數很大時,用索引查詢比全表掃描效率要差很多。
在連接查詢中,連接字段類型最好兼容或一致,否則索引失靈
2、索引KEY數據類型優先級:
int>char>varchar
3、插入大量數據時,先刪除索引,數據插入完成后,重建索引。
4、創建索引,加大排序緩存(number of sort buffers)。
5、創建索引順序:群聚索引>非群聚索引
6、創建大量索引后,最好備份數據庫(dump database),事務日志會記錄index創建事務等信息,使數據庫通過事務日志恢復可能比較慢。
7、創建群聚索引過程中,表處于獨占鎖模式,創建非群聚索引過程中,表處于共享鎖,可以select操作。
8、修改表影響了索引中列,需要修改索引列的統計數據,例如:修改authors表的所有索引的所有列統計,update index statistics authors
用SQL建立索引
為了給一個表建立索引,啟動任務欄SQL Sever程序組中的ISQL/w程序。進入查詢窗口后,輸入下面的語句:
| 1 | CREATE INDEX mycolumn_index ON mytable (myclumn) |
這個語句建立了一個名為mycolumn_index的索引。你可以給一個索引起任何名字,但你應該在索引名中包含所索引的字段名,這對你將來弄清楚建立該索引的意圖是有幫助的。
注意:
在本書中你執行任何SQL語句,都會收到如下的信息:
This command did not return data,and it did not return any rows
這說明該語句執行成功了。
索引mycolumn_index對表mytable的mycolumn字段進行。這是個非聚簇索引,也是個非唯一索引。(這是一個索引的缺省屬性)
如果你需要改變一個索引的類型,你必須刪除原來的索引并重建 一個。建立了一個索引后,你可以用下面的SQL語句刪除它:
| 1 | DROP INDEX mytable.mycolumn_index |
注意在DROP INDEX 語句中你要包含表的名字。在這個例子中,你刪除的索引是mycolumn_index,它是表mytable的索引。
要建立一個聚簇索引,可以使用關鍵字CLUSTERED。)記住一個表只能有一個聚簇索引。(這里有一個如何對一個表建立聚簇索引的例子:
| 1 | CREATE CLUSTERED INDEX mycolumn_clust_indexON mytable(mycolumn) |
如果表中有重復的記錄,當你試圖用這個語句建立索引時,會出現錯誤。但是有重復記錄的表也可以建立索引;你只要使用關鍵字ALLOW_DUP_ROW把這一點告訴SQL Sever即可:
| 1 2 | CREATE CLUSTERED INDEX mycolumn_cindex ONmytable(mycolumn) vj1fd}u\"? WITH ALLOW_DUP_ROW |
這個語句建立了一個允許重復記錄的聚簇索引。你應該盡量避免在一個表中出現重復記錄,但是,如果已經出現了,你可以使用這種方法。
要對一個表建立唯一索引,可以使用關鍵字UNIQUE。對聚簇索引和非聚簇索引都可以使用這個關鍵字。這里有一個例子:
| 1 | CREATE UNIQUE COUSTERED INDEXmyclumn_cindex ON mytable(mycolumn) |
這是你將經常使用的索引建立語句。無論何時,只要可以,你應該盡量對一個對一個表建立唯一聚簇索引來增強查詢操作。
最后,要建立一個對多個字段的索引──復合索引──在索引建立語句中同時包含多個字段名。下面的例子對firstname和lastname兩個字段建立索引:
| 1 | CREATE INDEX name_index ONusername(firstname,lastname) |
這個例子對兩個字段建立了單個索引。在一個復合索引中,你最多可以對16個字段進行索引。
用事務管理器建立索引
用事務管理器建立索引比用SQL語句容易的多。使用事務管理器,你可以看到已經建立的索引的列表,并可以通過圖形界面選擇索引選項。
使用事務管理器你可以用兩種方式建立索引:使用Manage Tables窗口或使用Manage Indexes窗口。
要用Manage Tables 窗口建立一個新索引,單擊按鈕Advanced Options(它看起來象一個前面有一加號的表)。這樣就打開了AdvancedOptions對話框。這個對話框有一部分標名為Primary Key。
要建立一個新索引,從下拉列表中選擇你想對之建立索引的字段名。如果你想建立一個對多字段的索引,你可以選擇多個字段名。你還可以選擇索引是聚簇的還是非聚簇的。在保存表信息后,索引會自動被建立。在Manage Tables窗口中的字段名旁邊,會出現一把鑰匙。
你已經為你的表建立了“主索引”。主索引必須對不包含空值的字段建立。另外,主索引強制一個字段成為唯一值字段。
要建立沒有這些限制的索引,你需要使用Manage Indexes窗口。從菜單中選擇Manage|Indexes,打開Manage Indexes 窗口。在Manage Indexes 窗口中,你可以通過下拉框選擇表和特定的索引。要建立一個新索引,從Index下拉框中選擇NewIndex.,然后就可以選擇要對之建立索引的字段。單擊按鈕Add,把字段加人到索引中。
你可以為你的索引選擇許多不同的選項。例如,你可以選擇該索引是聚簇的還是非聚簇的。你還可以指定該索引為唯一索引。設計好索引后,單擊按鈕Build,建立該索引。
?
總結
以上是生活随笔為你收集整理的sybase性能优化经验浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断今天是不是月末
- 下一篇: excel多个工作表求和案例