如下是對greenplum數據庫使用總結。html
CREATE INDEX i_test_tb_state_az ON test_tb(name_en) WHERE name_en = 'AZ';數據庫
當一個表很大的時候,爲每一行都建索引是很耗存儲空間的。若是經常使用的數據只有一小部分的話,徹底能夠只爲這部分數據創建索引,省時省力省空間。數組
省時:當作Insert和Update操做的時候,額外開銷更小。
省力:熱數據索引掃描更快。
省空間:索引不再用耗費大量磁盤了。
數據結構
1.不要給常常變動的列建索引。全表掃描性能很差時才須要建立索引。併發
2.不要建重複的索引並給索引命名。函數
3.低基數的列用bitmap索引。單列的查詢使用B-Tree索引。高併發
4.加載數據的時候先drop掉索引,加載以後再從新建立索引。oop
5.掃描一個大表的子集時,使用部分索引。post
6.重建立索引執行執行Analyze。Explain一下你經常使用的查詢,若是seq_scan的cost很高,能夠考慮創建索引。可是相應的,若是一個索引的idx scan不多被用到,就要考慮這個索引是否是還應該繼續存在了。畢竟,維護一個索引是耗時耗空間的事情。性能
7.在此以外,還能夠從如下幾點考慮:數據類型、索引創建的時間、索引存儲空間、數據更新時索引帶來的額外開銷、訪問速度等。
傳統索引方式(B-Tree)
說到傳統,B-Tree索引當仁不讓,它也是postgres裏的默認索引方式。B-Tree的中文名字是二叉平衡樹,每一個葉子結點的深度都是同樣的,特色是容許在O(logn)的時間內對所存儲的內容進行搜索、順序訪問、插入及刪除。
B-Tree索引做用和特色
B-Tree索引對於惟一值的索引來講是至關之理想的(好比id序號這類數據),它存儲的是一對對的鍵值和指針,指針指向被索引數據所在的heap上的位置。這裏說下什麼是heap。Heap(或者叫heap文件,用來區分同名不一樣義的數據結構heap)存儲着postgres表裏的全部數據(外部表除外)。heap裏邊的數據是無序的,這讓數據庫在向裏面添加數據的時候沒必要考慮排序的問題。目前postgres支持的索引中,只有B-Tree索引可以提供有序的查詢結果(也就是支持Order by和Limit),支持高併發場景(並行scan),支持merge join和包含index scan的nested loop操做。
BRIN (Block-Range Index)
名字裏有個range,顧名思義,這種索引存儲的是heap表內每一個block中數據的最大值和最小值。
BRIN索引做用和特色
首先,若是一整個block裏的數據都很是大或者很是小,不在咱們查詢的條件範圍內,就能夠將整個block排除出掃描範圍。這種索引對那些分佈是有序的數據很是有用,好比insert-only table的id或timestamp列。其次,由於只存儲最大值和最小值,BRIN帶來的空間消耗極小。另外,更新數據的時候,索引帶來的額外操做只有比較操做,也是至關高效的。BRIN對於含有多個列的索引是比較合適的選擇。可是,由於索引裏存儲的信息很是少,查找數據的時候消耗的時間也會很長,當查詢的數據範圍和一個block的範圍值有重疊時,就須要對這個block進行scan,若是有重疊的block不少,其實跟全表掃描的差異也不大了。
GIN (Generalized Inverted Index)索引
尤爲適用於有不少key或value的數據的索引,好比說文檔、JSON、整型數組等等。尤爲適用於重複數據不少的場景,這點和B-Tree正好相反。支持一條索引裏存在多個key。而B-Tree每條索引裏只能有一個key。好比新插入一條數據「foo bar」,GIN會拆分出兩個key:「foo」 和 「bar」。GIN索引內部數據結構總體上相似於B-Tree。不一樣的是,葉子結點上存儲的不是一個TID,而是不少TID的集合,這是GIN爲了存儲重複數據作的優化。GIN的葉子結點的數據有三種可能:
當只有一個TID的時候,和B-Tree同樣。當有不少TID的時候,那麼存儲的是一個列表(posting list)。當有很是很是多的TID的時候,葉子結點存儲的是一個指針,這個指針指向另外一棵樹(Posting Tree)的根結點。而Posting Tree裏面存儲了全部符合這一個entry的TIDs(以page爲存儲單元)。
GIN索引的Fast Updates特性:
GIN額外維護着一個列表,當有新的數據進入索引,不會直接進入索引樹,而是會先暫存在這個列表裏。固然,每一個對索引的搜索也都會額外的對這個列表進行掃描。當作vacuum操做的時候,會把這個列表裏的數據插入到索引樹上。不過,若是這個列表已經太大了,postgres不會傻傻等待用戶進行vacuum,會果斷地將它裏面的內容插入GIN索引樹。但有意思的是,雖然它叫Fast Updates,但這個特性會讓搜索變慢,由於每次搜索都要增長一次額外的列表掃描操做,因此不少用戶會把這個特性關掉。GIN索引適用於有大量重複關鍵字的全文索引,可是,當一個關鍵字出現次數太多時,返回結果也會很大,太大的結果集對用戶是沒有實際意義的,並且讀取並排序這麼多的數據會耗費很長時間。GIN提供了一個配置項gin_fuzzy_search_limit來控制這種狀況下返回結果集的上限。若是這個值非0,那麼查詢只會返回不超過設置值的一個子結果集,並且是隨機的。根據經驗,這個值設定爲5000-20000比較好。
GIST (Generalized Search Tree)索引
GIST的數據結構仍然是樹,但再也不是B-Tree了。支持地理座標、range類型(好比ip範圍)、hstore(key/value對)、整型數組、pg_trgm。若是是B-Tree,能夠按照range的最大值或最小值進行排序,但仍然避免不了每次查詢都要作掃描。GIST的作法,是將範圍差很少的數據彙集在一塊兒,造成一個個的「clusters」,每一個cluster的最大值和最小值都在根結點上記錄,這樣就能夠按照每一個cluster的總體範圍,排除掉那些根本不可能有重疊的cluster,大大下降了掃描成本。
GIST的用途
GIS (geographic information system)、尋找bounding box的頂點、找到最近的n個鄰居、全文檢索、整型數組,一句話總結:GIST適合上層結點的範圍能「包含」下層結點的類型。
SP-GIST (Space-Partitioned Generalized Search Tree)索引
雖然和GIST名字類似,但倒是徹底不一樣的索引類型,不是平衡樹,各個葉子節點的深度能夠不一樣。GIST各個cluster之間是能夠有範圍重疊的,可是SP-GIST不容許重疊。這是一個網址數據索引的例子,父節點是各個子節點的共有前綴,一個完整的鍵值在SP-GIST的樹上只存一次,每一部分分別存儲在從根結點到該鍵值葉子節點的路徑上。另一個常見的使用場景是索引座標點:將空間分割成不重疊的塊,每一個子節點再將父節點的空間細分。可是若是是空間裏的形狀,就沒法使用SP-GIST來索引了,由於形狀可能有重疊。
創建B樹索引:B樹索引是現網數據庫中最多見的索引類型之一,它適用範圍比較廣
1.適合於擁有重複值較少的字段。數據重複值越少,查詢數據選擇性越高,使用索引查詢數據的效率越高,反之則越低。
2.適用於對字段所在數據有少許修改的場合,例如字段有較少許的插入、修改、刪除等狀況,更新索引字段鍵值的代價適中。
3.適用於數據變化相對頻繁的OLTP系統。
4.須要佔用較高的存儲空間。
創建位圖索引:位圖索引是數據分析系統中常見的索引類型之一
1.適合於擁有較高重複值的字段,數據重複值對索引查詢的效率影響較少。
2.適用於對字段全部數據只讀或者極少修改的場合,更新索引字段鍵值將付出巨大的代價。
3.適用於數據變化不多的DSS數據分析系統。
4.須要較小的存儲空間。
創建哈希索引:Hash 索引只能處理簡單的等於比較,當一個索引了的列涉及到使用 = 操做符進行比較的時候,查詢規劃器會考慮使用 Hash 索引。
1.Hash索引的性能不比B-tree索引強。
2.Hash索引的建立時間會很長。
3.若是發生了數據庫崩潰,可能要重建Hash索引。
4.基於以上緣由不推薦使用Hash索引。
創建基於函數索引:B-tree索引的一種,建立基於函數的索引,適用於如下兩種狀況:
1.基於對索引鍵值進行各類函數運算,例如對字符串字段進行大寫轉換upper()運算。
2,.基於對一個或者多個字段進行各類運算,例如對兩個數值字段進行相加運算colA+colB等。
3.建立基於函數的索引,能夠提升在查詢條件中對索引使用基於特定函數的效率。所以,一個頻繁執行而且須要對特定字段進行特定函數轉換的查詢語句。可是創建基於函數的索引,沒法對使用字段自己或者對字段進行其它函數操做的查詢語句起到優化的效果。
創建部分索引:部分索引是創建在一個表的子集上的索引。
部分索引的主要動機是爲了不對普通數值(大量重複的數值)創建索引。由於在普通數值上的查詢就算使用索引也沒什麼好處,那麼還不如從索引中剔除這些大量重複的行。這樣能夠減少索引尺寸,提升那些真正使用索引的查詢的速度。同時它也能提升更新操做的速度,由於不是全部狀況都須要更新索引。
參考資料:
中文文檔:https://ask.greenplum.cn/topic/245/50723073
官方文檔:http://docs.greenplum.org/6-8/common/gpdb-features.html