數(shù)據(jù)庫性能優(yōu)化二:數(shù)據(jù)庫表優(yōu)化提升性能
更新時間:2013年01月02日 10:14:56 作者:
數(shù)據(jù)庫表優(yōu)化包括:設(shè)計規(guī)范化表、消除數(shù)據(jù)冗余、適當(dāng)?shù)娜哂唷⒃黾佑嬎懔?、索引、主鍵和外鍵的必要性等等,需要了解的朋友可以參考下
數(shù)據(jù)庫優(yōu)化包含以下三部分,數(shù)據(jù)庫自身的優(yōu)化,數(shù)據(jù)庫表優(yōu)化,程序操作優(yōu)化.此文為第二部分
優(yōu)化①:設(shè)計規(guī)范化表,消除數(shù)據(jù)冗余
數(shù)據(jù)庫范式是確保數(shù)據(jù)庫結(jié)構(gòu)合理,滿足各種查詢需要、避免數(shù)據(jù)庫操作異常的數(shù)據(jù)庫設(shè)計方式。滿足范式要求的表,稱為規(guī)范化表,范式產(chǎn)生于20世紀(jì)70年代初,一般表設(shè)計滿足前三范式就可以,在這里簡單介紹一下前三范式
先給大家看一下百度百科給出的定義:
第一范式(1NF)無重復(fù)的列
所謂第一范式(1NF)是指在關(guān)系模型中,對域添加的一個規(guī)范要求,所有的域都應(yīng)該是原子性的,即數(shù)據(jù)庫表的每一列都是不可分割的原子數(shù)據(jù)項,而不能是集合,數(shù)組,記錄等非原子數(shù)據(jù)項。
第二范式(2NF)屬性
在1NF的基礎(chǔ)上,非碼屬性必須完全依賴于碼[在1NF基礎(chǔ)上消除非主屬性對主碼的部分函數(shù)依賴]
第三范式(3NF)屬性
在1NF基礎(chǔ)上,任何非主屬性不依賴于其它非主屬性[在2NF基礎(chǔ)上消除傳遞依賴]
通俗的給大家解釋一下(可能不是最科學(xué)、最準(zhǔn)確的理解)
第一范式:屬性(字段)的原子性約束,要求屬性具有原子性,不可再分割;
第二范式:記錄的惟一性約束,要求記錄有惟一標(biāo)識,每條記錄需要有一個屬性來做為實體的唯一標(biāo)識。
第三范式:屬性(字段)冗余性的約束,即任何字段不能由其他字段派生出來,在通俗點就是:主鍵沒有直接關(guān)系的數(shù)據(jù)列必須消除(消除的辦法就是再創(chuàng)建一個表來存放他們,當(dāng)然外鍵除外)
如果數(shù)據(jù)庫設(shè)計達到了完全的標(biāo)準(zhǔn)化,則把所有的表通過關(guān)鍵字連接在一起時,不會出現(xiàn)任何數(shù)據(jù)的復(fù)本(repetition)。標(biāo)準(zhǔn)化的優(yōu)點是明顯的,它避免了數(shù)據(jù)冗余,自然就節(jié)省了空間,也對數(shù)據(jù)的一致性(consistency)提供了根本的保障,杜絕了數(shù)據(jù)不一致的現(xiàn)象,同時也提高了效率。
優(yōu)化②:適當(dāng)?shù)娜哂?,增加計算?/STRONG>
數(shù)據(jù)庫設(shè)計的實用原則是:在數(shù)據(jù)冗余和處理速度之間找到合適的平衡點
滿足范式的表一定是規(guī)范化的表,但不一定是最佳的設(shè)計。很多情況下會為了提高數(shù)據(jù)庫的運行效率,常常需要降低范式標(biāo)準(zhǔn):適當(dāng)增加冗余,達到以空間換時間的目的。比如我們有一個表,產(chǎn)品名稱,單價,庫存量,總價值。這個表是不滿足第三范式的,因為“總價值”可以由“單價”乘以“數(shù)量”得到,說明“金額”是冗余字段。但是,增加“總價值”這個冗余字段,可以提高查詢統(tǒng)計的速度,這就是以空間換時間的作法。合理的冗余可以分散數(shù)據(jù)量大的表的并發(fā)壓力,也可以加快特殊查詢的速度,冗余字段可以有效減少數(shù)據(jù)庫表的連接,提高效率。
其中"總價值"就是一個計算列,在數(shù)據(jù)庫中有兩種類型:數(shù)據(jù)列和計算列,數(shù)據(jù)列就是需要我們手動或者程序給予賦值的列,計算列是源于表中其他的數(shù)據(jù)計算得來,比如這里的"總價值"
在SQL中創(chuàng)建計算列:
create table table1
(
number decimal(18,4),
price money,
Amount as number*price --這里就是計算列
)
也可以再表設(shè)計中,直接手動添加或修改列屬性即可:如下圖
是否持久性,我們也需要注意:
如果是'否',說明這列是虛擬列,每次查詢的時候計算一次,而且那么它是不可以用來做check,foreign key或not null約束。
如果是'是',就是真實的列,不需要每次都計算,可以再此列上創(chuàng)建索引等等。
優(yōu)化③:索引
索引是一個表優(yōu)化的重要指標(biāo),在表優(yōu)化中占有極其重要的成分,所以將單獨寫一章”SQL索引一步到位“去告訴大家如何建立和優(yōu)化索引
優(yōu)化④:主鍵和外鍵的必要性
主鍵與外鍵的設(shè)計,在全局數(shù)據(jù)庫的設(shè)計中,占有重要地位。 因為:主鍵是實體的抽象,主鍵與外鍵的配對,表示實體之間的連接。
主鍵:根據(jù)第二范式,需要有一個字段去標(biāo)識這條記錄,主鍵無疑是最好的標(biāo)識,但是很多表也不一定需要主鍵,但是對于數(shù)據(jù)量大,查詢頻繁的數(shù)據(jù)庫表,一定要有主鍵,主鍵可以增加效率、防止重復(fù)等優(yōu)點。
主鍵的選擇也比較重要,一般選擇總的長度小的鍵,小的鍵的比較速度快,同時小的鍵可以使主鍵的B樹結(jié)構(gòu)的層次更少。
主鍵的選擇還要注意組合主鍵的字段次序,對于組合主鍵來說,不同的字段次序的主鍵的性能差別可能會很大,一般應(yīng)該選擇重復(fù)率低、單獨或者組合查詢可能性大的字段放在前面。
外鍵:外鍵作為數(shù)據(jù)庫對象,很多人認為麻煩而不用,實際上,外鍵在大部分情況下是很有用的,理由是:外鍵是最高效的一致性維護方法
數(shù)據(jù)庫的一致性要求,依次可以用外鍵、CHECK約束、規(guī)則約束、觸發(fā)器、客戶端程序,一般認為,離數(shù)據(jù)越近的方法效率越高。
謹慎使用級聯(lián)刪除和級聯(lián)更新,級聯(lián)刪除和級聯(lián)更新作為SQL SERVER 2000當(dāng)年的新功能,在2005作了保留,應(yīng)該有其可用之處。我這里說的謹慎,是因為級聯(lián)刪除和級聯(lián)更新有些突破了傳統(tǒng)的關(guān)于外鍵的定義,功能有點太過強大,使用前必須確定自己已經(jīng)把握好其功能范圍,否則,級聯(lián)刪除和級聯(lián)更新可能讓你的數(shù)據(jù)莫名其妙的被修改或者丟失。從性能看級聯(lián)刪除和級聯(lián)更新是比其他方法更高效的方法。
優(yōu)化⑤:存儲過程、視圖、函數(shù)的適當(dāng)使用
很多人習(xí)慣將復(fù)雜操作都放在應(yīng)用程序?qū)?,但如果你要?yōu)化數(shù)據(jù)訪問性能,將SQL代碼移植到數(shù)據(jù)庫上(使用存儲過程,視圖,函數(shù)和觸發(fā)器)也是一個很大的改進原因如下:
1. 存儲過程減少了網(wǎng)絡(luò)傳輸、處理及存儲的工作量,且經(jīng)過編譯和優(yōu)化,執(zhí)行速度快,易于維護,且表的結(jié)構(gòu)改變時,不影響客戶端的應(yīng)用程序
2、使用存儲過程,視圖,函數(shù)有助于減少應(yīng)用程序中SQL復(fù)制的弊端,因為現(xiàn)在只在一個地方集中處理SQL
3、使用數(shù)據(jù)庫對象實現(xiàn)所有的TSQL有助于分析TSQL的性能問題,同時有助于你集中管理TSQL代碼,更好的重構(gòu)TSQL代碼
優(yōu)化⑥:傳說中的‘三少原則'
①:數(shù)據(jù)庫的表越少越好
②:表的字段越少越好
③:字段中的組合主鍵、組合索引越少越好
當(dāng)然這里的少是相對的,是減少數(shù)據(jù)冗余的重要設(shè)計理念。
優(yōu)化⑦:分割你的表,減小表尺寸
如果你發(fā)現(xiàn)某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的做法是,以該表主鍵的某個值為界線,將該表的記錄水平分割為兩個表。
如果你若發(fā)現(xiàn)某個表的字段太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表
優(yōu)化⑧:字段設(shè)計原則
字段是數(shù)據(jù)庫最基本的單位,其設(shè)計對性能的影響是很大的。需要注意如下:
A、數(shù)據(jù)類型盡量用數(shù)字型,數(shù)字型的比較比字符型的快很多。
B、 數(shù)據(jù)類型盡量小,這里的盡量小是指在滿足可以預(yù)見的未來需求的前提下的。
C、 盡量不要允許NULL,除非必要,可以用NOT NULL+DEFAULT代替。
D、少用TEXT和IMAGE,二進制字段的讀寫是比較慢的,而且,讀取的方法也不多,大部分情況下最好不用。
E、 自增字段要慎用,不利于數(shù)據(jù)遷移
優(yōu)化①:設(shè)計規(guī)范化表,消除數(shù)據(jù)冗余
數(shù)據(jù)庫范式是確保數(shù)據(jù)庫結(jié)構(gòu)合理,滿足各種查詢需要、避免數(shù)據(jù)庫操作異常的數(shù)據(jù)庫設(shè)計方式。滿足范式要求的表,稱為規(guī)范化表,范式產(chǎn)生于20世紀(jì)70年代初,一般表設(shè)計滿足前三范式就可以,在這里簡單介紹一下前三范式
先給大家看一下百度百科給出的定義:
第一范式(1NF)無重復(fù)的列
所謂第一范式(1NF)是指在關(guān)系模型中,對域添加的一個規(guī)范要求,所有的域都應(yīng)該是原子性的,即數(shù)據(jù)庫表的每一列都是不可分割的原子數(shù)據(jù)項,而不能是集合,數(shù)組,記錄等非原子數(shù)據(jù)項。
第二范式(2NF)屬性
在1NF的基礎(chǔ)上,非碼屬性必須完全依賴于碼[在1NF基礎(chǔ)上消除非主屬性對主碼的部分函數(shù)依賴]
第三范式(3NF)屬性
在1NF基礎(chǔ)上,任何非主屬性不依賴于其它非主屬性[在2NF基礎(chǔ)上消除傳遞依賴]
通俗的給大家解釋一下(可能不是最科學(xué)、最準(zhǔn)確的理解)
第一范式:屬性(字段)的原子性約束,要求屬性具有原子性,不可再分割;
第二范式:記錄的惟一性約束,要求記錄有惟一標(biāo)識,每條記錄需要有一個屬性來做為實體的唯一標(biāo)識。
第三范式:屬性(字段)冗余性的約束,即任何字段不能由其他字段派生出來,在通俗點就是:主鍵沒有直接關(guān)系的數(shù)據(jù)列必須消除(消除的辦法就是再創(chuàng)建一個表來存放他們,當(dāng)然外鍵除外)
如果數(shù)據(jù)庫設(shè)計達到了完全的標(biāo)準(zhǔn)化,則把所有的表通過關(guān)鍵字連接在一起時,不會出現(xiàn)任何數(shù)據(jù)的復(fù)本(repetition)。標(biāo)準(zhǔn)化的優(yōu)點是明顯的,它避免了數(shù)據(jù)冗余,自然就節(jié)省了空間,也對數(shù)據(jù)的一致性(consistency)提供了根本的保障,杜絕了數(shù)據(jù)不一致的現(xiàn)象,同時也提高了效率。
優(yōu)化②:適當(dāng)?shù)娜哂?,增加計算?/STRONG>
數(shù)據(jù)庫設(shè)計的實用原則是:在數(shù)據(jù)冗余和處理速度之間找到合適的平衡點
滿足范式的表一定是規(guī)范化的表,但不一定是最佳的設(shè)計。很多情況下會為了提高數(shù)據(jù)庫的運行效率,常常需要降低范式標(biāo)準(zhǔn):適當(dāng)增加冗余,達到以空間換時間的目的。比如我們有一個表,產(chǎn)品名稱,單價,庫存量,總價值。這個表是不滿足第三范式的,因為“總價值”可以由“單價”乘以“數(shù)量”得到,說明“金額”是冗余字段。但是,增加“總價值”這個冗余字段,可以提高查詢統(tǒng)計的速度,這就是以空間換時間的作法。合理的冗余可以分散數(shù)據(jù)量大的表的并發(fā)壓力,也可以加快特殊查詢的速度,冗余字段可以有效減少數(shù)據(jù)庫表的連接,提高效率。
其中"總價值"就是一個計算列,在數(shù)據(jù)庫中有兩種類型:數(shù)據(jù)列和計算列,數(shù)據(jù)列就是需要我們手動或者程序給予賦值的列,計算列是源于表中其他的數(shù)據(jù)計算得來,比如這里的"總價值"
在SQL中創(chuàng)建計算列:
復(fù)制代碼 代碼如下:
create table table1
(
number decimal(18,4),
price money,
Amount as number*price --這里就是計算列
)
也可以再表設(shè)計中,直接手動添加或修改列屬性即可:如下圖

是否持久性,我們也需要注意:
如果是'否',說明這列是虛擬列,每次查詢的時候計算一次,而且那么它是不可以用來做check,foreign key或not null約束。
如果是'是',就是真實的列,不需要每次都計算,可以再此列上創(chuàng)建索引等等。
優(yōu)化③:索引
索引是一個表優(yōu)化的重要指標(biāo),在表優(yōu)化中占有極其重要的成分,所以將單獨寫一章”SQL索引一步到位“去告訴大家如何建立和優(yōu)化索引
優(yōu)化④:主鍵和外鍵的必要性
主鍵與外鍵的設(shè)計,在全局數(shù)據(jù)庫的設(shè)計中,占有重要地位。 因為:主鍵是實體的抽象,主鍵與外鍵的配對,表示實體之間的連接。
主鍵:根據(jù)第二范式,需要有一個字段去標(biāo)識這條記錄,主鍵無疑是最好的標(biāo)識,但是很多表也不一定需要主鍵,但是對于數(shù)據(jù)量大,查詢頻繁的數(shù)據(jù)庫表,一定要有主鍵,主鍵可以增加效率、防止重復(fù)等優(yōu)點。
主鍵的選擇也比較重要,一般選擇總的長度小的鍵,小的鍵的比較速度快,同時小的鍵可以使主鍵的B樹結(jié)構(gòu)的層次更少。
主鍵的選擇還要注意組合主鍵的字段次序,對于組合主鍵來說,不同的字段次序的主鍵的性能差別可能會很大,一般應(yīng)該選擇重復(fù)率低、單獨或者組合查詢可能性大的字段放在前面。
外鍵:外鍵作為數(shù)據(jù)庫對象,很多人認為麻煩而不用,實際上,外鍵在大部分情況下是很有用的,理由是:外鍵是最高效的一致性維護方法
數(shù)據(jù)庫的一致性要求,依次可以用外鍵、CHECK約束、規(guī)則約束、觸發(fā)器、客戶端程序,一般認為,離數(shù)據(jù)越近的方法效率越高。
謹慎使用級聯(lián)刪除和級聯(lián)更新,級聯(lián)刪除和級聯(lián)更新作為SQL SERVER 2000當(dāng)年的新功能,在2005作了保留,應(yīng)該有其可用之處。我這里說的謹慎,是因為級聯(lián)刪除和級聯(lián)更新有些突破了傳統(tǒng)的關(guān)于外鍵的定義,功能有點太過強大,使用前必須確定自己已經(jīng)把握好其功能范圍,否則,級聯(lián)刪除和級聯(lián)更新可能讓你的數(shù)據(jù)莫名其妙的被修改或者丟失。從性能看級聯(lián)刪除和級聯(lián)更新是比其他方法更高效的方法。
優(yōu)化⑤:存儲過程、視圖、函數(shù)的適當(dāng)使用
很多人習(xí)慣將復(fù)雜操作都放在應(yīng)用程序?qū)?,但如果你要?yōu)化數(shù)據(jù)訪問性能,將SQL代碼移植到數(shù)據(jù)庫上(使用存儲過程,視圖,函數(shù)和觸發(fā)器)也是一個很大的改進原因如下:
1. 存儲過程減少了網(wǎng)絡(luò)傳輸、處理及存儲的工作量,且經(jīng)過編譯和優(yōu)化,執(zhí)行速度快,易于維護,且表的結(jié)構(gòu)改變時,不影響客戶端的應(yīng)用程序
2、使用存儲過程,視圖,函數(shù)有助于減少應(yīng)用程序中SQL復(fù)制的弊端,因為現(xiàn)在只在一個地方集中處理SQL
3、使用數(shù)據(jù)庫對象實現(xiàn)所有的TSQL有助于分析TSQL的性能問題,同時有助于你集中管理TSQL代碼,更好的重構(gòu)TSQL代碼
優(yōu)化⑥:傳說中的‘三少原則'
①:數(shù)據(jù)庫的表越少越好
②:表的字段越少越好
③:字段中的組合主鍵、組合索引越少越好
當(dāng)然這里的少是相對的,是減少數(shù)據(jù)冗余的重要設(shè)計理念。
優(yōu)化⑦:分割你的表,減小表尺寸
如果你發(fā)現(xiàn)某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的做法是,以該表主鍵的某個值為界線,將該表的記錄水平分割為兩個表。
如果你若發(fā)現(xiàn)某個表的字段太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表
優(yōu)化⑧:字段設(shè)計原則
字段是數(shù)據(jù)庫最基本的單位,其設(shè)計對性能的影響是很大的。需要注意如下:
A、數(shù)據(jù)類型盡量用數(shù)字型,數(shù)字型的比較比字符型的快很多。
B、 數(shù)據(jù)類型盡量小,這里的盡量小是指在滿足可以預(yù)見的未來需求的前提下的。
C、 盡量不要允許NULL,除非必要,可以用NOT NULL+DEFAULT代替。
D、少用TEXT和IMAGE,二進制字段的讀寫是比較慢的,而且,讀取的方法也不多,大部分情況下最好不用。
E、 自增字段要慎用,不利于數(shù)據(jù)遷移
您可能感興趣的文章:
- 海量數(shù)據(jù)庫的查詢優(yōu)化及分頁算法方案
- SQL Server 數(shù)據(jù)庫優(yōu)化
- mysql 數(shù)據(jù)庫中my.ini的優(yōu)化 2G內(nèi)存針對站多 抗壓型的設(shè)置
- 開啟SQLSERVER數(shù)據(jù)庫緩存依賴優(yōu)化網(wǎng)站性能
- MySQL 聯(lián)合索引與Where子句的優(yōu)化 提高數(shù)據(jù)庫運行效率
- asp.net程序優(yōu)化 盡量減少數(shù)據(jù)庫連接操作
- 服務(wù)器維護小常識(硬盤內(nèi)容增加、數(shù)據(jù)庫優(yōu)化等)
- 數(shù)據(jù)庫性能優(yōu)化一:數(shù)據(jù)庫自身優(yōu)化提升性能
- Oracle SQL tuning 數(shù)據(jù)庫優(yōu)化步驟分享(圖文教程)
- oracle數(shù)據(jù)庫sql的優(yōu)化總結(jié)
- 優(yōu)化Mysql數(shù)據(jù)庫的8個方法
- Postgre數(shù)據(jù)庫Insert 、Query性能優(yōu)化詳解
- mysql中優(yōu)化和修復(fù)數(shù)據(jù)庫工具mysqlcheck詳細介紹
- Codeigniter操作數(shù)據(jù)庫表的優(yōu)化寫法總結(jié)
- MySQL數(shù)據(jù)庫優(yōu)化詳解
- 用實例詳解Python中的Django框架中prefetch_related()函數(shù)對數(shù)據(jù)庫查詢的優(yōu)化
- 數(shù)據(jù)庫學(xué)習(xí)建議之提高數(shù)據(jù)庫速度的十條建議
相關(guān)文章
SQLServer設(shè)置客戶端使用IP地址登錄的圖文詳解
這篇文章主要介紹了SQLServer設(shè)置客戶端使用IP地址登錄的圖文詳解,本文通過圖文并茂的形式給大家介紹的非常想詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12關(guān)于喜憂參半的SQL Server觸發(fā)器詳解
這篇文章主要給大家介紹了關(guān)于喜憂參半的SQL Server觸發(fā)器的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03SqlServer實現(xiàn)類似Oracle的before觸發(fā)器示例
本節(jié)主要介紹了SqlServer如何實現(xiàn)類似Oracle的before觸發(fā)器,需要的朋友可以參考下2014-08-08強制SQL Server執(zhí)行計劃使用并行提升在復(fù)雜查詢語句下的性能
最近在給一個客戶做調(diào)優(yōu)的時候發(fā)現(xiàn)一個很有意思的現(xiàn)象,對于一個復(fù)雜查詢(涉及12個表)建立必要的索引后,語句使用的IO急劇下降,但執(zhí)行時間不降反升,由原來的8秒升到20秒。2014-07-07Windows下SQL Serever 2012徹底卸載刪除教程
這篇文章主要為大家詳細介紹了Windows下SQL Serever2012徹底卸載刪除的教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03