⑴ 資料庫性能優化有哪些措施
1、調整數據結構的設計。這一部分在開發信息系統之前完成,程序員需要考慮是否使用ORACLE資料庫的分區功能,對於經常訪問的資料庫表是否需要建立索引等。
2、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什麼樣的體系結構,是使用傳統的Client/Server兩層體系結構,還是使用Browser/Web/Database的三層體系結構。不同的應用程序體系結構要求的資料庫資源是不同的。
3、調整資料庫sql語句。應用程序的執行最終將歸結為資料庫中的SQL語句執行,因此SQL語句的執行效率最終決定了ORACLE資料庫的性能。ORACLE公司推薦使用ORACLE語句優化器(Oracle Optimizer)和行鎖管理器(row-level manager)來調整優化SQL語句。
4、調整伺服器內存分配。內存分配是在信息系統運行過程中優化配置的,資料庫管理員可以根據資料庫運行狀況調整資料庫系統全局區(SGA區)的數據緩沖區、日誌緩沖區和共享池的大小;還可以調整程序全局區(PGA區)的大小。需要注意的是,SGA區不是越大越好,SGA區過大會佔用操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5、調整硬碟I/O,這一步是在信息系統開發之前完成的。資料庫管理員可以將組成同一個表空間的數據文件放在不同的硬碟上,做到硬碟之間I/O負載均衡。
6、調整操作系統參數,例如:運行在UNIX操作系統上的ORACLE資料庫,可以調整UNIX數據緩沖池的大小,每個進程所能使用的內存大小等參數。
資料庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,它產生於距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以後,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。資料庫有很多種類型,從最簡單的存儲有各種數據的表格到能夠進行海量數據存儲的大型資料庫系統都在各個方面得到了廣泛的應用。
在信息化社會,充分有效地管理和利用各類信息資源,是進行科學研究和決策管理的前提條件。資料庫技術是管理信息系統、辦公自動化系統、決策支持系統等各類信息系統的核心部分,是進行科學研究和決策管理的重要技術手段。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的「倉庫」,並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
(1)資料庫怎麼優化冗餘的表擴展閱讀
資料庫,簡單來說是本身可視為電子化的文件櫃--存儲電子文件的處所,用戶可以對文件中的數據進行新增、截取、更新、刪除等操作。
資料庫指的是以一定方式儲存在一起、能為多個用戶共享、具有盡可能小的冗餘度的特點、是與應用程序彼此獨立的數據集合。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的"倉庫",並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
⑵ 資料庫的多表大數據查詢應如何優化
1.應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:x0dx0aselect id from t where num is nullx0dx0a可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢:x0dx0aselect id from t where num=0x0dx0a2.應盡量避免在 where 子句顫洞中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。x0dx0a3.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:x0dx0aselect id from t where num=10 or num=20x0dx0a可以這樣查詢:x0dx0aselect id from t where num=10x0dx0aunion allx0dx0aselect id from t where num=20x0dx0a4.in 和 not in 也要慎用,因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如:x0dx0aselect id from t where num in(1,2,3)x0dx0a對於連續的數值,能用 between 就不要用 in 了:x0dx0aselect id from t where num between 1 and 3x0dx0a5.盡量避免在索引過的字元數據中,使用非打頭字母搜索。這也使得引擎無法利用索引。 x0dx0a見如下例子: x0dx0aSELECT * FROM T1 WHERE NAME LIKE 『%L%』 x0dx0aSELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=』L』 x0dx0aSELECT * FROM T1 WHERE NAME LIKE 『L%』 x0dx0a即使NAME欄位建有索引,前兩個查詢依然無法利用春嘩索引完成加快操作,引擎不得不對全表所有數據逐條操作來完成任務。而第三個查詢能夠使用索引來加快操作。x0dx0a6.必要時強制查詢優化器使用某個索引,如在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:x0dx0aselect id from t where num=@numx0dx0a可以改為強制查詢使用索引:x0dx0aselect id from t with(index(索引名)) where num=@numx0dx0a7.應盡量避免在 where 子句中對欄位進行表達式操扒洞行作,這將導致引擎放棄使用索引而進行全表掃描。如:x0dx0aSELECT * FROM T1 WHERE F1/2=100 x0dx0a應改為: x0dx0aSELECT * FROM T1 WHERE F1=100*2x0dx0aSELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=』5378』 x0dx0a應改為: x0dx0aSELECT * FROM RECORD WHERE CARD_NO LIKE 『5378%』x0dx0aSELECT member_number, first_name, last_name FROM members x0dx0aWHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21 x0dx0a應改為: x0dx0aSELECT member_number, first_name, last_name FROM members x0dx0aWHERE dateofbirth < DATEADD(yy,-21,GETDATE()) x0dx0a即:任何對列的操作都將導致表掃描,它包括資料庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。x0dx0a8.應盡量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:x0dx0aselect id from t where substring(name,1,3)='abc'--name以abc開頭的idx0dx0aselect id from t where datediff(day,createdate,-11-30')=0--『2005-11-30』生成的idx0dx0a應改為:x0dx0aselect id from t where name like 'abc%'x0dx0aselect id from t where createdate>=-11-30' and createdate<-12-1'x0dx0a9.不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。x0dx0a10.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。x0dx0a11.很多時候用 exists是一個好的選擇:x0dx0aelect num from a where num in(select num from b)x0dx0a用下面的語句替換:x0dx0aselect num from a where exists(select 1 from b where num=a.num)x0dx0aSELECT SUM(T1.C1)FROM T1 WHERE( x0dx0a(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0) x0dx0aSELECT SUM(T1.C1) FROM T1WHERE EXISTS( x0dx0aSELECT * FROM T2 WHERE T2.C2=T1.C2) x0dx0a兩者產生相同的結果,但是後者的效率顯然要高於前者。因為後者不會產生大量鎖定的表掃描或是索引掃描。
⑶ mysql怎麼優化,都要怎麼做
mysql優化是一個大方向,大的是要分布式、讀寫分離,小的是對sql語句進行優化。不過大多問的也是對sql語句優化,網上很多資料,我就大體說說。
1、explain+索引。
在你要查詢的語句前加explain,看下有沒有用到索引,如果出現type為all的,則說明有必要添加下索引。(附多表查詢速度比較:表關聯>exists>in)慢查詢優化是一大塊。
2、預統計。
很經常需要對歷史的數據進行過濾統計。比如移動需要統計上個月電話小時數超過N小時的人,那麼如果直接取原始數據,那將很慢,此時如果每天晚上凌晨都對數據進行預統計,統計每個人每天電話時數,那再來過濾就很快。
3、分表分區。
分表分區也是為了提高搜索速度。例如,公交車的gps行駛記錄,gps每隔15s報一次,一輛車一天運行12小時,一天就要插入4*60*12條記錄,N輛車就要再乘,其數量極大,所以經常按月分表,分表裡再按上報時間做日分區,這樣就達到很大的優化,想查詢某段時間,mysql很快就可以定位到。
4、表結構。
表結構很重要,經常需要多表關聯查詢一些欄位,有時可以冗餘下放到同一張表。
mysql優化很有意思,多去查閱些資料,多去嘗試,對你有好處的。
⑷ 什麼是資料庫中的數據冗餘如何消除數據冗餘
數據冗餘指數據之間的重復,也可以說是同一數據存儲在不同數據文件中的現象。可以說增加數據的獨立性和減少數據冗餘為企業范圍信息資源管理和大規模信息系統獲得成功的前提條件。
數據冗餘會妨礙資料庫中數據的完整性(integrality),也會造成存貯空間的浪費。盡可能地降低數據冗餘度,是資料庫設計的主要目標之一。關系模式的規范化理淪(以下稱NF理論)的主要思想之一就是最小冗餘原則,即規范化的關系模式在某種意義上應該冗餘度最小。
但是,NF理論沒有標準的概念可用,按等價原則,在有或沒有泛關系假設(universal relation assumption)等不同前提下,冗餘的定義可能有好幾種。
(4)資料庫怎麼優化冗餘的表擴展閱讀
數據的應用中為了某種目的採取數據冗餘方式。
1、重復存儲或傳輸數據以防止數據的丟失。
2、對數據進行冗餘性的編碼來防止數據的丟失、錯誤,並提供對錯誤數據進行反變換得到原始數據的功能。
3、為簡化流程所造成額數據冗餘。
4、為加快處理過程而將同一數據在不同地點存放。
5、為方便處理而使同一信息在不同地點有不同的表現形式。
6、大量數據的索引,一般在資料庫中經常使用。
7、方法類的信息冗餘。
8、為了完備性而配備的冗餘數據。
9、規則性的冗餘。根據法律、制度、規則等約束進行的。
10、為達到其他目的所進行的冗餘。
⑸ 什麼是資料庫中的數據冗餘如何消除數據冗餘
學號
姓名
課程名
成績
001
張三
數學
90
001
張三
語文
91
002
李四
數學
90
002
李四
語文
91
這樣的表稱為有數據冗餘
我們常常把這樣的表分為兩個表,如:
表1
學號
姓名
001
張三
002
李四
表2
學號
課程名
成績
001
數學
90
001
語文
91
002
數學
90
002
語文
91
這樣處理舉兆後既可滿足數據的第二範式要求,當然還不是最清冊好的。通過關系模式的範式可以消除數據冗餘,基本的數答答宏據庫應滿足第三範式(3NF)。
看看資料庫的「範式」內容
你就更好理解了。
⑹ 超詳細MySQL資料庫優化
資料庫優化一方面是找出系統的瓶頸,提高MySQL資料庫的整體性能,而另一方面需要合理的結構設計和參數調整,以提高用戶的相應速度,同時還要盡可能的節約系統資源,以便讓系統提供更大的負荷.
1. 優化一覽圖
2. 優化
筆者將優化分為了兩大類,軟優化和硬優化,軟優化一般是操作資料庫即可,而硬優化則是操作伺服器硬體及參數設置.
2.1 軟優化
2.1.1 查詢語句優化
1.首先我們可以用EXPLAIN或DESCRIBE(簡寫:DESC)命令分析一條查詢語句的執行信息.
2.例:
顯示:
其中會顯示索引和查詢數據讀取數據條數等信息.
2.1.2 優化子查詢
在MySQL中,盡量使用JOIN來代替子查詢.因為子查詢需要嵌套查詢,嵌套查詢時會建立一張臨時表,臨時表的建立和刪除都會有較大的系統開銷,而連接查詢不會創建臨時表,因此效率比嵌套子查詢高.
2.1.3 使用索引
索引是提高資料庫查詢速度最重要的方法之一,關於索引可以參高筆者<MySQL資料庫索引>一文,介紹比較詳細,此處記錄使用索引的三大注意事項:
2.1.4 分解表
對於欄位較多的表,如果某些欄位使用頻率較低,此時應當,將其分離出來從而形成新的表,
2.1.5 中間表
對於將大量連接查詢的表可以創建中間表,從而減少在查詢時造成的連接耗時.
2.1.6 增加冗餘欄位
類似於創建中間表,增加冗餘也是為了減少連接查詢.
2.1.7 分析表,,檢查表,優化表
分析表主要是分析表中關鍵字的分布,檢查表主要是檢查表中是否存在錯誤,優化表主要是消除刪除或更新造成的表空間浪費.
1. 分析表: 使用 ANALYZE 關鍵字,如ANALYZE TABLE user;
2. 檢查表: 使用 CHECK關鍵字,如CHECK TABLE user [option]
option 只對MyISAM有效,共五個參數值:
3. 優化表:使用OPTIMIZE關鍵字,如OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;
LOCAL|NO_WRITE_TO_BINLOG都是表示不寫入日誌.,優化表只對VARCHAR,BLOB和TEXT有效,通過OPTIMIZE TABLE語句可以消除文件碎片,在執行過程中會加上只讀鎖.
2.2 硬優化
2.2.1 硬體三件套
1.配置多核心和頻率高的cpu,多核心可以執行多個線程.
2.配置大內存,提高內存,即可提高緩存區容量,因此能減少磁碟I/O時間,從而提高響應速度.
3.配置高速磁碟或合理分布磁碟:高速磁碟提高I/O,分布磁碟能提高並行操作的能力.
2.2.2 優化資料庫參數
優化資料庫參數可以提高資源利用率,從而提高MySQL伺服器性能.MySQL服務的配置參數都在my.cnf或my.ini,下面列出性能影響較大的幾個參數.
2.2.3 分庫分表
因為資料庫壓力過大,首先一個問題就是高峰期系統性能可能會降低,因為資料庫負載過高對性能會有影響。另外一個,壓力過大把你的資料庫給搞掛了怎麼辦?所以此時你必須得對系統做分庫分表 + 讀寫分離,也就是把一個庫拆分為多個庫,部署在多個資料庫服務上,這時作為主庫承載寫入請求。然後每個主庫都掛載至少一個從庫,由從庫來承載讀請求。
2.2.4 緩存集群
如果用戶量越來越大,此時你可以不停的加機器,比如說系統層面不停加機器,就可以承載更高的並發請求。然後資料庫層面如果寫入並發越來越高,就擴容加資料庫伺服器,通過分庫分表是可以支持擴容機器的,如果資料庫層面的讀並發越來越高,就擴容加更多的從庫。但是這里有一個很大的問題:資料庫其實本身不是用來承載高並發請求的,所以通常來說,資料庫單機每秒承載的並發就在幾千的數量級,而且資料庫使用的機器都是比較高配置,比較昂貴的機器,成本很高。如果你就是簡單的不停的加機器,其實是不對的。所以在高並發架構里通常都有緩存這個環節,緩存系統的設計就是為了承載高並發而生。所以單機承載的並發量都在每秒幾萬,甚至每秒數十萬,對高並發的承載能力比資料庫系統要高出一到兩個數量級。所以你完全可以根據系統的業務特性,對那種寫少讀多的請求,引入緩存集群。具體來說,就是在寫資料庫的時候同時寫一份數據到緩存集群里,然後用緩存集群來承載大部分的讀請求。這樣的話,通過緩存集群,就可以用更少的機器資源承載更高的並發。
一個完整而復雜的高並發系統架構中,一定會包含:各種復雜的自研基礎架構系統。各種精妙的架構設計.因此一篇小文頂多具有拋磚引玉的效果,但是資料庫優化的思想差不多就這些了.
⑺ 怎麼進行mysql資料庫優化
有八個方面可以對mysql進行優化:
1、選取最適用的欄位屬性
MySQL可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得盡可能小。
2. 使用連接(JOIN)來代替子查詢(Sub-Queries)
MySQL從4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。
3、使用聯合(UNION)來代替手動創建的臨時表
MySQL從4.0的版本開始支持union查詢,它可以把需要使用臨時表的兩條或更多的select查詢合並的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。
4、事務
盡管我們可以使用子查詢(Sub-Queries)、連接(JOIN)和聯合(UNION)來創建各種各樣的查詢,但不是所有的資料庫操作都可以只用一條或少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。但是在這種情況下,當這個語句塊中的某一條語句運行出錯的時候,整個語句塊的操作就會變得不確定起來。設想一下,要把某個數據同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成數據的不完整,甚至會破壞資料庫中的數據。要避免這種情況,就應該使用事務,它的作用是:要麼語句塊中每條語句都操作成功,要麼都失敗
5、鎖定表
盡管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨占性,有時會影響資料庫的性能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的用戶請求只能暫時等待直到該事務結束。其實,有些情況下我們可以通過鎖定表的方法來獲得更好的性能。
6、使用外鍵
鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。
7、使用索引
索引是提高資料庫性能的常用方法,它可以令資料庫伺服器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當中包含有MAX(),MIN()和ORDERBY這些命令的時候,性能提高更為明顯。
8、優化的查詢語句
絕大多數情況下,使用索引可以提高查詢的速度,但如果SQL語句使用不恰當的話,索引將無法發揮它應有的作用。
⑻ 資料庫冗餘怎麼辦
它將冗餘數據選擇到一個游標中,並根據(LastName,FirstName)來分組(在我們這個方案中),然後打開游標然後循環地取出每一行,然後用與先前的取出的鍵值進行比較,如果這是第一次取出這個值,或者這個值不是冗餘鍵,那麼跳過這個記錄然後取下一個,不然的話,這就是這個組中的冗餘記錄,所以刪掉它.
讓我嫌宴櫻們運行一下這個存儲過程
BEGIN
DeleteDuplicates;
END;
/
SELECT LastName, FirstName, COUNT(*)
FROM Customers
GROUP BY LastName, FirstName
HAVING COUNT(*) > 1;
最後一個查詢語句沒有返回值,所以冗餘數據沒有了從表中取冗餘數據的過程完全是由定義在csr_Duplicates 這個游標中的SQL語句來實現的,PL/SQl只是用來實現刪除冗餘數,那麼能不能完全用SQL語句來實現呢?
二.SQL解決方案,使用RANK()刪除冗餘數據Oracle8i分析函數RANK()來枚舉每一個組中的元素,在我們的方案中, 我們應用這個方案,我們使用這個函數祥鉛動態的把冗餘數據連續的排芹叢列起來加上編號,組由Partintion by 這個語句來分開,然後用Order by 進行分組SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) SeqNumber
FROM Customers
ORDER BY LastName, FirstName;
SQL
Listing 7. Output of single SQL statement that uses RANK()
顯示的是根據記錄的條數的個數來顯示尤其對於冗餘數據
ID LASTNAME FIRSTNAME SEQNUMBER
----- --------------- ---------- ----------
1018 Blake Becky 1
1013 Blue Don 1
1000 Bradley Tom 1
1002 Chang Jim 1
1008 Griffith David 1
1020 Hill Larry 1
1004 King Chuck 1
1005 Krieger Jeff 1
1012 Krieger Jeff 2
1017 Krieger Jeff 3
1003 Loney Julie 1
1007 Lord Don 1
1015 Mason Paul 1
1006 Monroe John 1
1009 Simon Michael 1
1010 Simon Michael 2
1001 Stone Tony 1
1011 Stone Tony 2
1014 Stone Tony 3
1016 Stone Tony 4
1019 Stone Tony 5
我們可以看一到,SeqNumber這一列中的數值,冗餘數據是根據ID號由小到大進行的排序,所有的冗餘數據的SqlNumber都大於一,所有的非冗餘數據都等於一,所以我們取自己所需,刪除那麼沒用的SELECT ID, LastName, FirstName
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) AS SeqNumber
FROM Customers)
WHERE SeqNumber > 1;
SQL
Listing 8. 冗餘鍵的鍵值
有七行必須被刪除
ID LASTNAME FIRSTNAME
----- --------------- ----------
1012 Krieger Jeff
1017 Krieger Jeff
1010 Simon Michael
1011 Stone Tony
1014 Stone Tony
1016 Stone Tony
1019 Stone Tony
7 rows selected.這顯示有七行需要刪除,還是用上一個表我測試了一下這個代碼,它用了77秒種就刪除了所有的數據准備好了用Sql語句來刪除冗餘數據,版本一它執行了135秒
DELETE
FROM CUSTOMERS
WHERE ID IN
(SELECT ID
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) AS SeqNumber
FROM Customers)
WHERE SeqNumber > 1);
我們可以看到最後的兩行語句對表中的數據進行了排序,這不是有效的,所以我們來優化一下最後一個查詢語句,把Rank()函數應用到只含有冗餘數據的組,而不是所有的列下面這個語句是比較有效率的,雖然它不像上一個查詢那樣精簡SELECT ID, LastName, FirstName
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) AS SeqNumber
FROM
(SELECT ID, LastName, FirstName
FROM Customers
WHERE (LastName, FirstName) IN (SELECT LastName, FirstName
FROM Customers
GROUP BY LastName, FirstName
HAVING COUNT(*) > 1)))
WHERE SeqNumber > 1;
選擇冗餘數據只用了26秒鍾,這樣就提高了67%的性能,這樣就提高了將這個作為子查詢的刪除查詢的效率,
DELETE
FROM Customers
WHERE ID IN
(SELECT ID
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) AS SeqNumber
FROM
(SELECT ID, LastName, FirstName
FROM Customers
WHERE (LastName, FirstName) IN (SELECT LastName, FirstName
FROM Customers
GROUP BY LastName, FirstName
HAVING COUNT(*) > 1)))
WHERE SeqNumber > 1);
現在只用了47秒鍾的就完成的上面的任務,比起上一個136秒,這是一個很大的進步,相比之下,存儲過程用了56秒,這樣存儲過程有些慢了使用PL/SQL語句我們和我們以上的代碼,會得到更好的更精確的代碼,和提高你代碼的執行效率,雖然對於從資料庫中枚舉數據PL/SQL對於Sql兩者沒有什麼差別,但是對於數據的比較上,PL/SQL就比SQL要快很多,但是如果冗餘數據量比較小的話,我們盡量使用SQL而不使用PL/SQL如果你的數據表沒有主鍵的話,那麼你可以參考其它技術
Rank()其它的方法
使用Rank()函數你可以對選擇你所保留的數據,(或者是小ID的或者是大ID 的,就由RECDate這個列來決定這種情況下,你可以把REcdate加入到(Orderby )子句中,倒序或者正序
這是一種保留最大Id的一種解決方案
DELETE
FROM Customers
WHERE ID IN
(SELECT ID
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName, FirstName ORDER BY RecDate DESC, ID) AS SeqNumber
FROM
(SELECT ID, LastName, FirstName, RecDate
FROM Customers
WHERE (LastName, FirstName) IN (SELECT LastName, FirstName
FROM Customers
GROUP BY LastName, FirstName
HAVING COUNT(*) > 1)))
WHERE SeqNumber > 1);
這種技術保證了你可以控制每一個表中的保留的組,假設你有一個資料庫,有一個促銷或者有一個折扣信息,比如一個團體可以使用這種促銷5次,或者個人可以使用這個折扣三次,為了指出要保留的組的個數,你可以在where 和having子句中進行設置,那麼你將刪除所有大於你
設置有數的冗餘組
DELETE
FROM Customers
WHERE ID IN
(SELECT ID
FROM
(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,
FirstName ORDER BY ID) AS SeqNumber
FROM
(SELECT ID, LastName, FirstName
FROM Customers
WHERE (LastName, FirstName) IN (SELECT LastName, FirstName
FROM Customers
GROUP BY LastName, FirstName
HAVING COUNT(*) > 3)))
WHERE SeqNumber > 3);
As you can see, using the RANK() function allows you to eliminate plicates in a
single SQL statement and gives you more capabilities by extending the power of
your
queries.
正如你所見使用Rank()可以消除冗餘數據而且能給你很大的可伸展性
⑼ 如何優化一個有100萬條記錄的資料庫表
可以採取兩個手段:
第一:將資料庫表拆分到不同的庫中,比如 tblMEMBER 就可以拆分到 DB1 與 DB2 中去。 實際嫌皮毀上,可以拆分到 DB001 ... DB100 甚至更多握銷的庫中間去。 DB1 與 DB2 最好不在一塊硬碟上。
第二:如果更大量級的數據,則最好拆分到不同的資料庫伺服器中去。 資料庫的拆分帶來的是查詢等操作的復雜性。簡單地可以通過 hash 或者 按序號 匹配不同的資料庫。復雜一些,應該設置一個獨立的應用伺服器芹備(軟體)協調其中的操作。
⑽ 誰知道資料庫優化設計方案有哪些
本文首先討論了基於第三範式的資料庫表的基本設計,著重論述了建立主鍵和索引的策略和方案,然後從資料庫表的擴展設計和庫表對象的放置等角度概述了資料庫管理系統的優化方案。
關鍵詞: 優化(Optimizing) 第三範式(3NF) 冗餘數據(Rendant Data) 索引(Index) 數據分割(Data Partitioning) 對象放置(Object Placement)
1 引言
資料庫優化的目標無非是避免磁碟I/O瓶頸、減少CPU利用率和減少資源競爭。為了便於讀者閱讀和理解,筆者參閱了Sybase、Informix和Oracle等大型資料庫系統參考資料,基於多年的工程實踐經驗,從基本表設計、擴展設計和資料庫表對象放置等角度進行討論,著重討論了如何避免磁碟I/O瓶頸和減少資源競爭,相信讀者會一目瞭然。
2 基於第三範式的基本表設計
在基於表驅動的信息管理系統(MIS)中,基本表的設計規范是第三範式(3NF)。第三範式的基本特徵是非主鍵屬性只依賴於主鍵屬性。基於第三範式的資料庫表設計具有很多優點:一是消除了冗餘數據,節省了磁碟存儲空間;二是有良好的數據完整性限制,即基於主外鍵的參照完整限制和基於主鍵的實體完整性限制,這使得數據容易維護,也容易移植和更新;三是數據的可逆性好,在做連接(Join)查詢或者合並表時不遺漏、也不重復;四是因消除了冗餘數據(冗餘列),在查詢(Select)時每個數據頁存的數據行就多,這樣就有效地減少了邏輯I/O,每個Cash存的頁面就多,也減少物理I/O;五是對大多數事務(Transaction)而言,運行性能好;六是物理設計(Physical Design)的機動性較大,能滿足日益增長的用戶需求。
在基本表設計中,表的主鍵、外鍵、索引設計佔有非常重要的地位,但系統設計人員往往只注重於滿足用戶要求,而沒有從系統優化的高度來認識和重視它們。實際上,它們與系統的運行性能密切相關。現在從系統資料庫優化角度討論這些基本概念及其重要意義:
(1)主鍵(Primary Key):主鍵被用於復雜的SQL語句時,頻繁地在數據訪問中被用到。一個表只有一個主鍵。主鍵應該有固定值(不能為Null或預設值,要有相對穩定性),不含代碼信息,易訪問。把常用(眾所周知)的列作為主鍵才有意義。短主鍵最佳(小於25bytes),主鍵的長短影響索引的大小,索引的大小影響索引頁的大小,從而影響磁碟I/O。主鍵分為自然主鍵和人為主鍵。自然主鍵由實體的屬性構成,自然主鍵可以是復合性的,在形成復合主鍵時,主鍵列不能太多,復合主鍵使得Join*作復雜化、也增加了外鍵表的大小。人為主鍵是,在沒有合適的自然屬性鍵、或自然屬性復雜或靈敏度高時,人為形成的。人為主鍵一般是整型值(滿足最小化要求),沒有實際意義,也略微增加了表的大小;但減少了把它作為外鍵的表的大小。
(2)外鍵(Foreign Key):外鍵的作用是建立關系型資料庫中表之間的關系(參照完整性),主鍵只能從獨立的實體遷移到非獨立的實體,成為後者的一個屬性,被稱為外鍵。
(3)索引(Index):利用索引優化系統性能是顯而易見的,對所有常用於查詢中的Where子句的列和所有用於排序的列創建索引,可以避免整表掃描或訪問,在不改變表的物理結構的情況下,直接訪問特定的數據列,這樣減少數據存取時間;利用索引可以優化或排除耗時的分類*作;把數據分散到不同的頁面上,就分散了插入的數據;主鍵自動建立了唯一索引,因此唯一索引也能確保數據的唯一性(即實體完整性);索引碼越小,定位就越直接;新建的索引效能最好,因此定期更新索引非常必要。索引也有代價:有空間開銷,建立它也要花費時間,在進行Insert、Delete和Update*作時,也有維護代價。索引有兩種:聚族索引和非聚族索引。一個表只能有一個聚族索引,可有多個非聚族索引。使用聚族索引查詢數據要比使用非聚族索引快。在建索引前,應利用資料庫系統函數估算索引的大小。
① 聚族索引(Clustered Index):聚族索引的數據頁按物理有序儲存,佔用空間小。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢或高度重復的列(連續磁碟掃描);被用於連接Join*作的列;被用於Order by和Group by子句的列。聚族索引不利於插入*作,另外沒有必要用主鍵建聚族索引。
② 非聚族索引(Nonclustered Index):與聚族索引相比,佔用空間大,而且效率低。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢(在沒有聚族索引時)、主鍵或外鍵列、點(指針類)或小范圍(返回的結果域小於整表數據的20%)查詢;被用於連接Join*作的列、主鍵列(范圍查詢);被用於Order by和Group by子句的列;需要被覆蓋的列。對只讀表建多個非聚族索引有利。索引也有其弊端,一是創建索引要耗費時間,二是索引要佔有大量磁碟空間,三是增加了維護代價(在修改帶索引的數據列時索引會減緩修改速度)。那麼,在哪種情況下不建索引呢?對於小表(數據小於5頁)、小到中表(不直接訪問單行數據或結果集不用排序)、單值域(返回值密集)、索引列值太長(大於20bitys)、容易變化的列、高度重復的列、Null值列,對沒有被用於Where子語句和Join查詢的列都不能建索引。另外,對主要用於數據錄入的,盡可能少建索引。當然,也要防止建立無效索引,當Where語句中多於5個條件時,維護索引的開銷大於索引的效益,這時,建立臨時表存儲有關數據更有效。
批量導入數據時的注意事項:在實際應用中,大批量的計算(如電信話單計費)用C語言程序做,這種基於主外鍵關系數據計算而得的批量數據(文本文件),可利用系統的自身功能函數(如Sybase的BCP命令)快速批量導入,在導入資料庫表時,可先刪除相應庫表的索引,這有利於加快導入速度,減少導入時間。在導入後再重建索引以便優化查詢。
(4)鎖:鎖是並行處理的重要機制,能保持數據並發的一致性,即按事務進行處理;系統利用鎖,保證數據完整性。因此,我們避免不了死鎖,但在設計時可以充分考慮如何避免長事務,減少排它鎖時間,減少在事務中與用戶的交互,杜絕讓用戶控制事務的長短;要避免批量數據同時執行,尤其是耗時並用到相同的數據表。鎖的徵用:一個表同時只能有一個排它鎖,一個用戶用時,其它用戶在等待。若用戶數增加,則Server的性能下降,出現「假死」現象。如何避免死鎖呢?從頁級鎖到行級鎖,減少了鎖徵用;給小表增加無效記錄,從頁級鎖到行級鎖沒有影響,若在同一頁內競爭有影響,可選擇合適的聚族索引把數據分配到不同的頁面;創建冗餘表;保持事務簡短;同一批處理應該沒有網路交互。
(5)查詢優化規則:在訪問資料庫表的數據(Access Data)時,要盡可能避免排序(Sort)、連接(Join)和相關子查詢*作。經驗告訴我們,在優化查詢時,必須做到:
① 盡可能少的行;
② 避免排序或為盡可能少的行排序,若要做大量數據排序,最好將相關數據放在臨時表中*作;用簡單的鍵(列)排序,如整型或短字元串排序;
③ 避免表內的相關子查詢;
④ 避免在Where子句中使用復雜的表達式或非起始的子字元串、用長字元串連接;
⑤ 在Where子句中多使用「與」(And)連接,少使用「或」(Or)連接;
⑥ 利用臨時資料庫。在查詢多表、有多個連接、查詢復雜、數據要過濾時,可以建臨時表(索引)以減少I/O。但缺點是增加了空間開銷。
除非每個列都有索引支持,否則在有連接的查詢時分別找出兩個動態索引,放在工作表中重新排序。
3 基本表擴展設計
基於第三範式設計的庫表雖然有其優越性(見本文第一部分),然而在實際應用中有時不利於系統運行性能的優化:如需要部分數據時而要掃描整表,許多過程同時競爭同一數據,反復用相同行計算相同的結果,過程從多表獲取數據時引發大量的連接*作,當數據來源於多表時的連接*作;這都消耗了磁碟I/O和CPU時間。
尤其在遇到下列情形時,我們要對基本表進行擴展設計:許多過程要頻繁訪問一個表、子集數據訪問、重復計算和冗餘數據,有時用戶要求一些過程優先或低的響應時間。
如何避免這些不利因素呢?根據訪問的頻繁程度對相關表進行分割處理、存儲冗餘數據、存儲衍生列、合並相關表處理,這些都是克服這些不利因素和優化系統運行的有效途徑。
3.1 分割表或儲存冗餘數據
分割表分為水平分割表和垂直分割表兩種。分割表增加了維護數據完整性的代價。
水平分割表:一種是當多個過程頻繁訪問數據表的不同行時,水平分割表,並消除新表中的冗餘數據列;若個別過程要訪問整個數據,則要用連接*作,這也無妨分割表;典型案例是電信話單按月分割存放。另一種是當主要過程要重復訪問部分行時,最好將被重復訪問的這些行單獨形成子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但在分割表以後,增加了維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。
垂直分割表(不破壞第三範式),一種是當多個過程頻繁訪問表的不同列時,可將表垂直分成幾個表,減少磁碟I/O(每行的數據列少,每頁存的數據行就多,相應佔用的頁就少),更新時不必考慮鎖,沒有冗餘數據。缺點是要在插入或刪除數據時要考慮數據的完整性,用存儲過程維護。另一種是當主要過程反復訪問部分列時,最好將這部分被頻繁訪問的列數據單獨存為一個子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但這增加了重疊列的維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。垂直分割表可以達到最大化利用Cache的目的。
總之,為主要過程分割表的方法適用於:各個過程需要表的不聯結的子集,各個過程需要表的子集,訪問頻率高的主要過程不需要整表。在主要的、頻繁訪問的主表需要表的子集而其它主要頻繁訪問的過程需要整表時則產生冗餘子集表。
注意,在分割表以後,要考慮重新建立索引。
3.2 存儲衍生數據
對一些要做大量重復性計算的過程而言,若重復計算過程得到的結果相同(源列數據穩定,因此計算結果也不變),或計算牽扯多行數據需額外的磁碟I/O開銷,或計算復雜需要大量的CPU時間,就考慮存儲計算結果(冗餘儲存)。現予以分類說明:
若在一行內重復計算,就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器更新這個新列。
若對表按類進行重復計算,就增加新表(一般而言,存放類和結果兩列就可以了)存儲相關結果。但若參與計算的列被更新時,就必須要用觸發器立即更新、或存儲過程或應用代碼批量更新這個新表。
若對多行進行重復性計算(如排名次),就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器或存儲過程更新這個新列。
總之,存儲冗餘數據有利於加快訪問速度;但違反了第三範式,這會增加維護數據完整性的代價,必須用觸發器立即更新、或存儲過程或應用代碼批量更新,以維護數據的完整性。
3.3 消除昂貴結合
對於頻繁同時訪問多表的一些主要過程,考慮在主表內存儲冗餘數據,即存儲冗餘列或衍生列(它不依賴於主鍵),但破壞了第三範式,也增加了維護難度。在源表的相關列發生變化時,必須要用觸發器或存儲過程更新這個冗餘列。當主要過程總同時訪問兩個表時可以合並表,這樣可以減少磁碟I/O*作,但破壞了第三範式,也增加了維護難度。對父子表和1:1關系表合並方法不同:合並父子表後,產生冗餘表;合並1:1關系表後,在表內產生冗餘數據。
4 資料庫對象的放置策略
資料庫對象的放置策略是均勻地把數據分布在系統的磁碟中,平衡I/O訪問,避免I/O瓶頸。
⑴ 訪問分散到不同的磁碟,即使用戶數據盡可能跨越多個設備,多個I/O運轉,避免I/O競爭,克服訪問瓶頸;分別放置隨機訪問和連續訪問數據。
⑵ 分離系統資料庫I/O和應用資料庫I/O。把系統審計表和臨時庫表放在不忙的磁碟上。
⑶ 把事務日誌放在單獨的磁碟上,減少磁碟I/O開銷,這還有利於在障礙後恢復,提高了系統的安全性。
⑷ 把頻繁訪問的「活性」表放在不同的磁碟上;把頻繁用的表、頻繁做Join*作的表分別放在單獨的磁碟上,甚至把把頻繁訪問的表的欄位放在不同的磁碟上,把訪問分散到不同的磁碟上,避免I/O爭奪;
⑸ 利用段分離頻繁訪問的表及其索引(非聚族的)、分離文本和圖像數據。段的目的是平衡I/O,避免瓶頸,增加吞吐量,實現並行掃描,提高並發度,最大化磁碟的吞吐量。利用邏輯段功能,分別放置「活性」表及其非聚族索引以平衡I/O。當然最好利用系統的默認段。另外,利用段可以使備份和恢復數據更加靈活,使系統授權更加靈活。