華為面試題之資料庫sql優化方案

2021-08-28 04:05:05 字數 3793 閱讀 4048

答案:我們應該在過濾條件使用順序調整成分區條件/索引條件/基本資料型別條件

是一種物理資料庫設計技術,dba和資料庫建模人員對其相當熟悉。雖然分割槽技術可以實現很多效果,但其主要目的是為了在特定的sql操作中減少資料讀寫的總量以縮減響應時間。

分割槽主要有兩種形式://這裡一定要注意行和列的概念(row是行,column是列)

水平分割槽(horizontal partitioning)

這種形式分割槽是對錶的行進行分割槽,通過這樣的方式不同分組裡面的物理列分割的資料集得以組合,從而進行個體分割(單分割槽)或集體分割(1個或多個分割槽)。所有在表中定義的列在每個資料集中都能找到,所以表的特性依然得以保持。

舉個簡單例子:乙個包含十年發票記錄的表可以被分割槽為十個不同的分割槽,每個分割槽包含的是其中一年的記錄。(朋奕注:這裡具體使用的分割槽方式我們後面再說,可以先說一點,一定要通過某個屬性列來分割,譬如這裡使用的列就是年份)

垂直分割槽(vertical partitioning)

這種分割槽方式一般來說是通過對錶的垂直劃分來減少目標表的寬度,使某些特定的列被劃分到特定的分割槽,每個分割槽都包含了其中的列所對應的行。

舉個簡單例子:乙個包含了大text和blob列的表,這些text和blob列又不經常被訪問,這時候就要把這些不經常使用的text和blob了劃分到另乙個分割槽,在保證它們資料相關性的同時還能提高訪問速度。

在資料庫**商開始在他們的資料庫引擎中建立分割槽(主要是水平分割槽)時,dba和建模者必須設計好錶的物理分割槽結構,不要儲存冗餘的資料(不同表中同時都包含父表中的資料)或相互聯結成乙個邏輯父物件(通常是檢視)。這種做法會使水平分割槽的大部分功能失效,有時候也會對垂直分割槽產生影響。

在掃瞄操作中,如果mysql的優化器知道哪個分割槽中才包含特定查詢中需要的資料,它就能直接去掃瞄那些分割槽的資料,而不用浪費很多時間掃瞄不需要的地方了。需要舉個例子?好啊,百萬行的表劃分為10個分割槽,每個分割槽就包含十萬行資料,那麼查詢分割槽需要的時間僅僅是全表掃瞄的十分之一了,很明顯的對比。同時對十萬行的表建立索引的速度也會比百萬行的快得多得多。如果你能把這些分割槽建立在不同的磁碟上,這時候的i/o讀寫速度就「不堪設想」(沒用錯詞,真的太快了,理論上100倍的速度提公升啊,這是多麼快的響應速度啊,所以有點不堪設想了)了。

分割槽技術可以讓dba對資料的管理能力提公升。通過優良的分割槽,dba可以簡化特定資料操作的執行方式。例如:dba在對某些分割槽的內容進行刪除的同時能保證餘下的分割槽的資料完整性(這是跟對錶的資料刪除這種大動作做比較的)。

此外分割槽是由mysql系統直接管理的,dba不需要手工的去劃分和維護。例如:這個例如沒意思,不講了,如果你是dba,只要你劃分了分割槽,以後你就不用管了就是了。

##建立索引

# alter table

alter table table_name add index index_name (column_list)

alter table table_name add unique (column_list)

alter table table_name add primary key (column_list)

# create table 不能用create index語句建立primary key索引

create index index_name on table_name (column_list)

create unique index index_name on table_name (column_list)

##刪除索引

drop index index_name on talbe_name

alter table table_name drop index index_name

alter table table_name drop primary key

##檢視索引

show index from tblname;

show keys from tblname;

表的主關鍵字自動建立唯一索引

表的字段唯一約束

直接條件查詢的字段

查詢中與其它表關聯的字段,字段常常建立了外來鍵關係

查詢中排序的字段

查詢中統計或分組統計的字段

表記錄太少

如果乙個表只有5條記錄,採用索引去訪問記錄的話,那首先需訪問索引表,再通過索引表訪問資料表,一般索引表與資料表不在同乙個資料塊,這種情況下oracle至少要往返讀取資料塊兩次。而不用索引的情況下oracle會將所有的資料一次讀出,處理速度顯然會比用索引快。

經常插入、刪除、修改的表

注意事項:

首先,應當考慮表空間和磁碟空間是否足夠。我們知道索引也是一種資料,在建立索引的時候勢必也會占用大量表空間。因此在對一大表建立索引的時候首先應當考慮的是空間容量問題。其次,在對建立索引的時候要對錶進行加鎖,因此應當注意操作在業務空閒的時候進行。

效能調整方面:

首當其衝的考慮因素便是磁碟i/o。物理上,應當盡量把索引與資料分散到不同的磁碟上(不考慮陣列的情況)。邏輯上,資料表空間與索引表空間分開。這是在建索引時應當遵守的基本準則。

其次,我們知道,在建立索引的時候要對錶進行全表的掃瞄工作,因此,應當考慮調大初始化引數db_file_multiblock_read_count的值。一般設定為32或更大。再次,建立索引除了要進行全表掃瞄外同時還要對資料進行大量的排序操作,因此,應當調整排序區的大小。

建立索引

對於查詢佔主要的應用來說,索引顯得尤為重要。很多時候效能問題很簡單的就是因為我們忘了新增索引而造成的,或者說沒有新增更為有效的索引導致。如果不加索引的話,那麼查詢任何哪怕只是一條特定的資料都會進行一次全表掃瞄,如果一張表的資料量很大而符合條件的結果又很少,那麼不加索引會引起致命的效能下降。但是也不是什麼情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麼優勢,還會影響到更新速度,這被稱為過度索引。

復合索引

如果在area、age兩列上建立復合索引的話將帶來更高的效率。如果我們建立了(area, age,salary)的復合索引,那麼其實相當於建立了(area,age,salary)、(area,age)、(area)三個索引,這被稱為最佳左字首特性。因此我們在建立復合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。

索引不會包含有null值的列

所以我們在資料庫設計時不要讓字段的預設值為null。

使用短索引

對串列進行索引,如果可能應該指定乙個字首長度。例如,如果有乙個char(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和i/o操作。

排序的索引問題

mysql查詢只使用乙個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列建立復合索引。

like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是乙個問題。like 「%aaa%」 不會使用索引而like 「aaa%」可以使用索引。

不要在列上進行運算

select * from users where year(adddate)

不使用not in和操作

not in操作都不會使用索引將進行全表掃瞄。not in可以not exists代替

面試題 資料庫優化

從以下方面去考慮 建立並使用盡量索引,以及避免全表掃瞄 索引是什麼 索引分類 between and 代替in exists 代替in union代替in where子句將過濾大量資料的條件放靠後 避免where子句中使用is not null is null 函式運輸 算術運算 等判斷 2 程式語...

SQL優化 面試題

因為現在面試經常需要問的需要sql優化,問的具體操作步驟時候的常見做法,所以網上總結這些操作步驟 sql優化的具體操作 1 在表中建立索引,優先考慮where group by使用到的字段。2 盡量避免使用select 返回無用的字段會降低查詢效率。如下 select from t 優化方式 使用具...

PHP經典面試題 資料庫優化

mysql資料庫優化 php學習過程中或者面試過程中少不了的乙個重要知識點,那就是關於資料庫的優化問題,本人經過查閱資料並驗證,總結了幾點比較淺層的資料庫優化方法,小白可以參考,大神勿噴。忘了什麼時候發現的一張關於mysql資料庫優化的梯形圖了,一直收藏著,感覺很有道理 從圖中可以很明顯的看出mys...