日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引

發(fā)布時間:2023/12/2 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考《PostgreSQL11.2-中文手冊》

下面這個鏈接,講的通俗易懂,可以看看。

數(shù)據(jù)分析師不得不知道的SQL優(yōu)化 - 鑫獲 - 博客園?www.cnblogs.com

索引是提高數(shù)據(jù)庫性能的常用途徑。比起沒有索引,使用索引可以讓數(shù)據(jù)庫服務(wù)器更快找到

并獲取特定行。

但是索引同時也會增加數(shù)據(jù)庫系統(tǒng)的日常管理負(fù)擔(dān),因此我們應(yīng)該聰明地使用索引。

簡介

CREATE TABLE test1 ( id integer, content varchar)

假設(shè)對上表做出如下查詢:

SELECT content FROM test1 WHERE id = constant

在沒有事前準(zhǔn)備的情況下,系統(tǒng)不得不掃描整個test1表,一行一行地去找到所有匹配的

項。如果test1中有很多行但是只有一小部分行(可能是0或者1)需要被該查詢返回,這顯

然是一種低效的方式。

但是如果系統(tǒng)被指示維護(hù)一個在id列上的索引,它就能使用一種更有效的方式來定位匹配行。例如,它可能僅僅需要遍歷一棵搜索樹的幾層而已。

類似的方法也被用于大部分非小說書籍中:經(jīng)常被讀者查找的術(shù)語和概念被收集在一個字母

序索引中放在書籍的末尾。感興趣的讀者可以相對快地掃描索引并跳到合適的頁而不需要閱

讀整本書來尋找感興趣的材料。正如作者的任務(wù)是準(zhǔn)備好讀者可能會查找的術(shù)語一樣,數(shù)據(jù)

庫程序員也需要預(yù)見哪些索引會有用。

正如前面討論的,下列命令可以用來在id列上創(chuàng)建一個索引:

CREATE INDEX test1_id_index ON test1 (id);

索引的名字test1_id_index可以自由選擇,但我們最好選擇一個能讓我們想起該索引用途的

名字。

為了移除一個索引,可以使用DROP INDEX命令。索引可以隨時被創(chuàng)建或刪除

一旦一個索引被創(chuàng)建,就不再需要進(jìn)一步的干預(yù):系統(tǒng)會在表更新時更新索引,而且會在它

覺得使用索引比順序掃描表效率更高時使用索引。

但我們可能需要定期地運(yùn)行ANALYZE命令

來更新統(tǒng)計信息以便查詢規(guī)劃器能做出正確的決定。通過Chapter 14 的信息可以了解如何找

出一個索引是否被使用以及規(guī)劃器在何時以及為什么會選擇不使用索引。

索引也會使帶有搜索條件的UPDATE和DELETE命令受益。此外索引還可以在連接搜索中使用。

因此,一個定義在連接條件列上的索引可以顯著地提高連接查詢的速度。

在一個大表上創(chuàng)建一個索引會耗費(fèi)很長的時間。默認(rèn)情況下,PostgreSQL允許在索引創(chuàng)建時

并行地進(jìn)行讀(SELECT命令),但寫(INSERT、UPDATE和DELETE)則會被阻塞直到索引創(chuàng)建完成。

在生產(chǎn)環(huán)境中這通常是不可接受的。在創(chuàng)建索引時允許并行的寫是可能的,但是有些警告需要注意,更多信息可以參考并發(fā)構(gòu)建索引。

一個索引被創(chuàng)建后,系統(tǒng)必須保持它與表同步。這增加了數(shù)據(jù)操作的負(fù)擔(dān)。因此哪些很少或

從不在查詢中使用的索引應(yīng)該被移除。

索引類型

PostgreSQL提供了多種索引類型: B-tree、Hash、GiST、SP-GiST 、GIN 和 BRIN。每一種

索引類型使用了 一種不同的算法來適應(yīng)不同類型的查詢。

B-tree 索引

默認(rèn)情況下, CREATE INDEX命令創(chuàng)建適合于大部分情況的B-tree 索引。

B-tree可以在可排序數(shù)據(jù)上的處理等值和范圍查詢。特別地,PostgreSQL的查詢規(guī)劃器會

在任何一種涉及到以下操作符的已索引列上考慮使用B-tree索引:

< <= = >= >

將這些操作符組合起來,例如BETWEEN和IN,也可以用B-tree索引搜索實現(xiàn)。同樣,在索引

列上的IS NULL或IS NOT NULL條件也可以在B-tree索引中使用。

優(yōu)化器也會將B-tree索引用于涉及到模式匹配操作符LIKE和~ 的查詢,前提是如果模式是一

個常量且被固定在字符串的開頭—例如:col LIKE 'foo%'或者col ~ '^foo', 但在col

LIKE '%bar'上則不會。但是,如果我們的數(shù)據(jù)庫沒有使用C區(qū)域設(shè)置,我們需要創(chuàng)建一個

具有特殊操作符類的索引來支持模式匹配查詢,參見下面的Section 11.10 。同樣可以將Btree索引用于ILIKE和~*,但僅當(dāng)模式以非字母字符開始,即不受大小寫轉(zhuǎn)換影響的字符。

B-tree索引也可以用于檢索排序數(shù)據(jù)。這并不會總是比簡單掃描和排序更快,但是總是有用

的。

Hash索引

Hash索引只能處理簡單等值比較。不論何時當(dāng)一個索引列涉及到一個使用了=操作符的比較

時,查詢規(guī)劃器將考慮使用一個Hash索引。

CREATE INDEX name ON table USING HASH (column)

GiST索引

GiST索引并不是一種單獨(dú)的索引,而是可以用于實現(xiàn)很多不同索引策略的基礎(chǔ)設(shè)施。相應(yīng)

地,可以使用一個GiST索引的特定操作符根據(jù)索引策略(操作符類)而變化。作為一個例

子,PostgreSQL的標(biāo)準(zhǔn)捐獻(xiàn)包中包括了用于多種二維幾何數(shù)據(jù)類型的GiST操作符類,它用來

支持使用下列操作符的索引化查詢:

<< &< &> >> <<| &<| |&> |>> @> <@ ~= &&

(這些操作符的含義見Section 9.11 )Table 64.1 中給出了標(biāo)準(zhǔn)發(fā)布中所包括的 GiST 操作

符類。contrib集合中還包括了很多其他GiST操作符類,可見Chapter 64 。

GiST索引也有能力優(yōu)化“最近鄰”搜索,例如:

SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;

它將找到離給定目標(biāo)點最近的10個位置。能夠支持這種查詢的能力同樣取決于被使用的特定

操作符類。 在Table 64.1中,“Ordering Operators”列中列出了可以在這種方法中使用的

操作符。

SP-GiST索引

GiST相似,SP-GiST索引為支持多種搜索提供了一種基礎(chǔ)結(jié)構(gòu)。SPGiST 允許實現(xiàn)眾多不同的非平衡的基于磁盤的數(shù)據(jù)結(jié)構(gòu),例如四叉樹、k-d樹和radix樹。

作為一個例 子,PostgreSQL的標(biāo)準(zhǔn)捐獻(xiàn)包中包含了一個用于二維點的SP-GiST操作符類,它

用于支持使用下列操作符的索引化查詢:

<< >> ~= <@ <^ >^

GIN 索引

GIN 索引是“倒排索引”,它適合于包含多個組成值的數(shù)據(jù)值,例如數(shù)組。倒排索引中為

每一個組成值都包含一個單獨(dú)的項,它可以高效地處理測試指定組成值是否存在的查詢。

與 GiST 和 SP-GiST相似, GIN 可以支持多種不同的用戶定義的索引策略,并且可以與一

個 GIN 索引配合使用的特定操作符取決于索引策略。

作為一個例子,PostgreSQL的標(biāo)準(zhǔn)貢獻(xiàn)

包中包含了用于數(shù)組的GIN操作符類,它用于支持使用下列操作符的索引化查詢:

<@ @> = &&

BRIN 索引

BRIN 索引(塊范圍索引的縮寫)存儲有關(guān)存放在一個表的連續(xù)物理塊范圍上的值摘要信

息。與 GiST、SP-GiST 和 GIN 相似,BRIN 可以支持很多種不同的索引策略,并且可以與一

個 BRIN 索引配合使用的特定操作符取決于索引策略。對于具有線性排序順序的數(shù)據(jù)類型,

被索引的數(shù)據(jù)對應(yīng)于每個塊范圍的列中值的最小值和最大值,使用這些操作符來支持用到索

引的查詢:

< <= = >= >

多列索引

一個索引可以定義在表的多個列上;

CREATE INDEX test2_mm_idx ON test2 (major, minor);

目前,只有 B-tree、GiST、GIN 和 BRIN 索引類型支持多列索引,最多可以指定32個列(該

限制可以在源代碼文件pg_config_manual.h中修改,但是修改后需要重新編PostgreSQL)。

B-tree索引

一個B-tree索引可以用于條件中涉及到任意索引列子集的查詢,但是當(dāng)先導(dǎo)列(即最左邊的

那些列)上有約束條件時索引最為有效。

確切的規(guī)則是:

  • 在先導(dǎo)列上的等值約束,加上第一個無等值約束的列上的不等值約束,將被用于限制索引被掃描的部分。
  • 在這些列右邊的列上的約束將在索引中被檢查,這樣它們適當(dāng)節(jié)約了對表的訪問,但它們并未減小索引被掃描的部分。
  • 例如,在(a, b, c)上有一個索引并且給定一個查詢條件WHERE a = 5 AND b >= 42 AND c < 77,對索引的掃描將從第一個具有a = 5和b = 42的項開始向上進(jìn)行,直到最后一個具有a = 5的項。

    在掃描過程中,具有c>= 77的索引項將被跳過,但是它們還是會被掃描到。這個索引在原則上可以被用于在b和/或c上有約束而在a上沒有約束的查詢,但是整個索引都不得不被掃描,因此在大部分情況下規(guī)劃器寧可使用一個順序的表掃描來替代索引。

    多列GiST索引

    一個多列GiST索引可以用于條件中涉及到任意索引列子集的查詢。在其余列上的條件將限制

    由索引返回的項,但是第一列上的條件是決定索引上掃描量的最重要因素。當(dāng)?shù)谝涣兄芯哂?/p>

    很少的可區(qū)分值時,一個GiST索引將會相對比較低效,即便在其他列上有很多可區(qū)分值。

    其他多列索引

    一個GIN索引可以用于條件中涉及到任意索引列子集的查詢。與B-tree和GiST不同,GIN的搜

    索效率與查詢條件中使用哪些索引列無關(guān)。

    多列 BRIN 索引可以被用于涉及該索引被索引列的任意子集的查詢條件。和 GIN 相似且不

    同于 B-樹 或者 GiST,索引搜索效率與查詢條件使用哪個索引列無關(guān)。在單個表上使用多個

    BRIN 索引來取代一個多列 BRIN 索引的唯一原因是為了使用不同的pages_per_range存儲參

    數(shù)。

    當(dāng)然,要使索引起作用,查詢條件中的列必須要使用適合于索引類型的操作符,使用其他操

    作符的子句將不會被考慮使用索引。

    多列索引應(yīng)該較少地使用。在絕大多數(shù)情況下,單列索引就足夠了且能節(jié)約時間和空間。具

    有超過三個列的索引不太有用,除非該表的使用是極端程式化的。Section 11.5 以及Section 11.9 中有對不同索引配置優(yōu)點的討論。

    索引和ORDER BY

    除了簡單地查找查詢要返回的行外,一個索引可能還需要將它們以指定的順序傳遞。這使得

    查詢中的ORDER BY不需要獨(dú)立的排序步驟。在PostgreSQL當(dāng)前支持的索引類型中,只有Btree可以產(chǎn)生排序后的輸出,其他索引類型會把行以一種沒有指定的且與實現(xiàn)相關(guān)的順序返

    回。

    規(guī)劃器會考慮以兩種方式來滿足一個ORDER BY說明:掃描一個符合說明的可用索引,或者先

    以物理順序掃描表然后再顯式排序。對于一個需要掃描表的大部分的查詢,一個顯式的排序

    很可能比使用一個索引更快,因為其順序訪問模式使得它所需要的磁盤I/O更少。只有在少

    數(shù)行需要被取出時,索引才會更有用。

    一種重要的特殊情況是ORDER BY與LIMIT n聯(lián)合使用:一個顯式的排序?qū)幚硭械臄?shù)據(jù)來確定最前面的n行,但如果有一個符合ORDER BY的索引,前n行將會被直接獲取且根本不需要掃描剩下的數(shù)據(jù)。

    默認(rèn)情況下,B-tree索引將它的項以升序方式存儲,并將空值放在最后。這意味著對列x上

    索引的一次前向掃描將產(chǎn)生滿足ORDER BY x(或者更長的形式:ORDER BY x ASC NULLS

    LAST)的結(jié)果。索引也可以被后向掃描,產(chǎn)生滿足ORDER BY x DESC(ORDER BY x DESC NULLS

    FIRST, NULLS FIRST是ORDER BY DESC的默認(rèn)情況)。

    我們可以在創(chuàng)建B-tree索引時通過ASC、DESC、NULLS FIRST和NULLS LAST選項來改變索引的

    排序,例如:

    CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);

    CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);

    一個以升序存儲且將空值前置的索引可以根據(jù)掃描方向來支持ORDER BY x ASC NULLS FIRST或ORDER BY x DESC NULLS LAST。

    讀者可能會疑惑為什么要麻煩地提供所有四個選項,因為兩個選項連同可能的后向掃描可以

    覆蓋所有ORDER BY的變體。在單列索引中這些選項確實有冗余,但是在多列索引中它們卻很

    有用。考慮(x, y)上的一個兩列索引:它可以通過前向掃描滿足ORDER BY x, y,或者通過

    后向掃描滿足ORDER BY x DESC, y DESC。但是應(yīng)用可能需要頻繁地使用ORDER BY x ASC,

    y DESC。這樣就沒有辦法從通常的索引中得到這種順序,但是如果將索引定義為(x ASC, y

    DESC)或者(x DESC, y ASC)就可以產(chǎn)生這種排序。

    顯然,具有非默認(rèn)排序的索引是相當(dāng)專門的特性,但是有時它們會為特定查詢提供巨大的速

    度提升。是否值得維護(hù)這樣一個索引取決于我們會多頻繁地使用需要特殊排序的查詢。

    組合多個索引

    只有查詢子句中在索引列上使用了索引操作符類中的操作符并且通過AND連接時才能使用單

    一索引。例如,給定一個(a, b) 上的索引,查詢條件WHERE a = 5 AND b = 6可以使用該索

    引,而查詢WHERE a = 5 OR b = 6不能直接使用該索引。

    幸運(yùn)的是,PostgreSQL具有組合多個索引(包括多次使用同一個索引)的能力來處理那些不

    能用單個索引掃描實現(xiàn)的情況。系統(tǒng)能在多個索引掃描之間安排AND和OR條件。

    例如,

    WHERE x = 42 OR x = 47 OR x = 53 OR x= 99這樣一個查詢可以被分解成為四個獨(dú)立的在x上索引掃描,每一個掃描使用其中一個條件。

    這些查詢的結(jié)果將被“或”起來形成最后的結(jié)果。另一個例子是如果我們在x和y上都有獨(dú)立的索引,WHERE x = 5 AND y = 6這樣的查詢的一種可能的實現(xiàn)方式就是分別使用兩個索引配合相應(yīng)的條件,然后將結(jié)果“與”起來得到最后的結(jié)果行。

    為了組合多個索引,系統(tǒng)掃描每一個所需的索引并在內(nèi)存中準(zhǔn)備一個位圖用于指示表中符合

    索引條件的行的位置。然后這些位圖會被根據(jù)查詢的需要“與”和“或”起來。最后,實際

    的表行將被訪問并返回。表行將被以物理順序訪問,因為位圖就是以這種順序布局的。

    這意味著原始索引中的任何排序都會被丟失,并且如果存在一個ORDER BY子句就需要一個單獨(dú)的排序步驟。

    由于這個原因以及每一個附加的索引都需要額外的時間,即使有額外的索引可用,規(guī)劃器有時也會選擇使用單一索引掃描。

    在所有的應(yīng)用(除了最簡單的應(yīng)用)中,可能會有多種有用的索引組合,數(shù)據(jù)庫開發(fā)人員必

    須做出權(quán)衡以決定提供哪些索引。

    有時候多列索引最好,但是有時更好的選擇是創(chuàng)建單獨(dú)的索引并依賴于索引組合特性。例如,如果我們的查詢中有時只涉及到列x,有時候只涉及到列y,還有時候會同時涉及到兩列,我們可以選擇在x和y上創(chuàng)建兩個獨(dú)立索引然后依賴索引組合來處理同時涉及到兩列的查詢。我們當(dāng)然也可以創(chuàng)建一個(x, y)上的多列索引。

    當(dāng)查詢同時涉及到兩列時,該索引會比組合索引效率更高,但是正如Section 11.3 中討論的,它在只涉及到y(tǒng)的查詢中幾乎完全無用,因此它不能是唯一的一個索引。一個多列索引和一個y上的獨(dú)立索引的組合將會工作得很好。

    多列索引可以用于那些只涉及到x的查詢,盡管它比x上的獨(dú)立索引更大且更慢。最后一種選擇是創(chuàng)建所有三個索引,但是這種選擇最適合表經(jīng)常被執(zhí)行所有三種查詢但是很少被更新的情況。如果其中一種查詢要明顯少于其他類型的查詢,

    我們可能需要只為常見類型的查詢創(chuàng)建兩個索引。

    唯一索引

    索引也可以被用來強(qiáng)制列值的唯一性,或者是多個列組合值的唯一性

    CREATE UNIQUE INDEX name ON table (column [, ...]);

    當(dāng)前,只有B-tree能夠被聲明為唯一。

    當(dāng)一個索引被聲明為唯一時,索引中不允許多個表行具有相同的索引值。空值被視為不相

    同。一個多列唯一索引將會拒絕在所有索引列上具有相同組合值的表行。

    PostgreSQL會自動為定義了一個唯一約束或主鍵的表創(chuàng)建一個唯一索引。該索引包含組成主

    鍵或唯一約束的所有列(可能是一個多列索引),它也是用于強(qiáng)制這些約束的機(jī)制。

    不需要手工在唯一列上創(chuàng)建索引,如果那樣做也只是重復(fù)了自動創(chuàng)建的索引而已。

    表達(dá)式索引

    一個索引列并不一定是底層表的一個列,也可以是從表的一列或多列計算而來的一個函數(shù)或

    者標(biāo)量表達(dá)式。這種特性對于根據(jù)計算結(jié)果快速獲取表中內(nèi)容是有用的。

    例如,一種進(jìn)行大小寫不敏感比較的常用方法是使用lower函數(shù)

    SELECT * FROM test1 WHERE lower(col1) = 'value'

    這種查詢可以利用一個建立在lower(col1)函數(shù)結(jié)果之上的索引:

    CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1))

    如果我們將該索引聲明為UNIQUE,它將阻止創(chuàng)建在col1值上只有大小寫不同的行

    另一個例子,如果我們經(jīng)常進(jìn)行如下的查詢:

    SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';

    那么值得創(chuàng)建一個這樣的索引:

    CREATE INDEX people_names ON people ((first_name || ' ' || last_name))

    正如第二個例子所示,CREATE INDEX命令的語法通常要求在被索引的表達(dá)式周圍書寫圓括

    號。而如第一個例子所示,當(dāng)表達(dá)式只是一個函數(shù)調(diào)用時可以省略掉圓括號;

    索引表達(dá)式的維護(hù)代價較為昂貴,因為在每一個行被插入或更新時都得為它重新計算相應(yīng)的

    表達(dá)式。然而,索引表達(dá)式在進(jìn)行索引搜索時卻不需要重新計算,因為它們的結(jié)果已經(jīng)被存

    儲在索引中了。

    在上面兩個例子中,系統(tǒng)將會發(fā)現(xiàn)查詢的條件是WHERE indexedcolumn= 'constant',因此查詢的速度將等同于其他簡單索引查詢。因此,表達(dá)式索引對于檢索速度遠(yuǎn)比插入和更新速度重要的情況非常有用。

    部分索引

    一個部分索引是建立在表的一個子集上,而該子集則由一個條件表達(dá)式(被稱為部分索引

    的謂詞)定義。而索引中只包含那些符合該謂詞的表行的項。部分索引是一種專門的特性,

    但在很多種情況下它們也很有用。

    使用部分索引的一個主要原因是避免索引公值。由于搜索一個公值的查詢(一個在所有表行

    中占比超過一定百分比的值)不會使用索引,所以完全沒有理由將這些行保留在索引中。這

    可以減小索引的尺寸,同時也將加速使用索引的查詢。它也將加速很多表更新操作,因為這

    種索引并不需要在所有情況下都被更新。Example 11.1 展示了一種可能的應(yīng)用:

    Example 11.1. 建立一個部分索引來排除公值

    假設(shè)我們要在一個數(shù)據(jù)庫中保存網(wǎng)頁服務(wù)器訪問日志。大部分訪問都來自于我們組織內(nèi)的IP

    地址,但是有些來自于其他地方(如使用撥號連接的員工)。如果我們主要通過IP搜索來自

    于外部的訪問,我們就沒有必要索引對應(yīng)于我們組織內(nèi)網(wǎng)的IP范圍。

    假設(shè)有這樣一個表:

    CREATE TABLE access_log ( url varchar, client_ip inet, ... )

    用以下命令可以創(chuàng)建適用于我們的部分索引:

    CREATE INDEX access_log_client_ip_ix ON access_log (client_ip) WHERE NOT (client_ip > inet '192.168.100.0' AND client_ip < inet '192.168.100.255')

    一個使用該索引的典型查詢是:

    SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';

    一個不能使用該索引的查詢:

    SELECT * FROM access_log WHERE client_ip = inet '192.168.100.23';

    可以看到部分索引查詢要求公值能被預(yù)知,因此部分索引最適合于數(shù)據(jù)分布不會改變的情

    況。當(dāng)然索引也可以偶爾被重建來適應(yīng)新的數(shù)據(jù)分布,但是這會增加維護(hù)負(fù)擔(dān)。

    Example 11.2 展示了部分索引的另一個可能的用途:從索引中排除那些查詢不感興趣的值。

    這導(dǎo)致了上述相同的好處,但它防止了通過索引來訪問“不感興趣的”值,即便在這種情況

    下一個索引掃描是有益的。顯然,為這種場景建立部分索引需要很多考慮和實驗。

    Example 11.2. 建立一個部分索引來排除不感興趣的值

    如果我們有一個表包含已上賬和未上賬的訂單,其中未上賬的訂單在整個表中占據(jù)一小部分

    且它們是最經(jīng)常被訪問的行。我們可以通過只在未上賬的行上創(chuàng)建一個索引來提高性能。創(chuàng)

    建索引的命令如下:

    CREATE INDEX orders_unbilled_index ON orders (order_nr) WHERE billed is not true

    使用該索引的一個可能查詢是:

    SELECT * FROM orders WHERE billed is not true AND order_nr < 10000;

    然而,索引也可以用于完全不涉及order_nr的查詢,例如

    SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;

    這并不如在amount列上部分索引有效,因為系統(tǒng)必須掃描整個索引。然而,如果有相對較少

    的未上賬訂單,使用這個部分索引來查找未上賬訂單將會更好。

    注意這個查詢將不會使用該索引:

    SELECT * FROM orders WHERE order_nr = 3501;

    訂單3501可能在已上賬訂單或未上賬訂單中。

    Example 11.2 也顯示索引列和謂詞中使用的列并不需要匹配。PostgreSQL支持使用任意謂詞

    的部分索引,只要其中涉及的只有被索引表的列。然而,記住謂詞必須匹配在將要受益于索

    引的查詢中使用的條件。更準(zhǔn)確地,只有當(dāng)系統(tǒng)能識別查詢的WHERE條件從數(shù)學(xué)上索引的謂

    詞時,一個部分索引才能被用于一個查詢。PostgreSQL并不能給出一個精致的定理證明器來

    識別寫成不同形式在數(shù)學(xué)上等價的表達(dá)式(一方面創(chuàng)建這種證明器極端困難,另一方面即便

    能創(chuàng)建出來對于實用也過慢)。系統(tǒng)可以識別簡單的不等蘊(yùn)含,例如“x < 1”蘊(yùn)含“x

    < 2”;否則謂詞條件必須準(zhǔn)確匹配查詢的WHERE條件中的部分,或者索引將不會被識別為可

    用。匹配發(fā)生在查詢規(guī)劃期間而不是運(yùn)行期間。因此,參數(shù)化查詢子句無法配合一個部分索

    引工作。例如,對于參數(shù)的所有可能值來說,一個具有參數(shù)“x < ?”的預(yù)備查詢絕不會蘊(yùn)

    含“x < 2”。

    部分索引的第三種可能的用途并不要求索引被用于查詢。其思想是在一個表的子集上創(chuàng)建一

    個唯一索引,如Example 11.3 所示。這對那些滿足索引謂詞的行強(qiáng)制了唯一性,而對那些不

    滿足的行則沒有影響。

    Example 11.3. 建立一個部分唯一索引

    假設(shè)我們有一個描述測試結(jié)果的表。我們希望保證其中對于一個給定的主題和目標(biāo)組合只有

    一個“成功”項,但其中可能會有任意多個“不成功”項。實現(xiàn)它的方式是:

    CREATE TABLE tests ( subject text, target text, success boolean, ... )CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success;

    當(dāng)有少數(shù)成功測試和很多不成功測試時這是一種特別有效的方法。

    最后,一個部分索引也可以被用來重載系統(tǒng)的查詢規(guī)劃選擇。同樣,具有特殊分布的數(shù)據(jù)集

    可能導(dǎo)致系統(tǒng)在它并不需要索引的時候選擇使用索引。在此種情況下可以被建立,這樣它將

    不會被那些無關(guān)的查詢所用。通常,PostgreSQL會對索引使用做出合理的選擇(例如,它會

    在檢索公值時避開索引,這樣前面的例子只能節(jié)約索引尺寸,它并非是避免索引使用所必需

    的),非常不正確的規(guī)劃選擇則需要作為故障報告。

    記住建立一個部分索引意味著我們知道的至少和查詢規(guī)劃器所知的一樣多,尤其是我們知道

    什么時候一個索引會是有益的。構(gòu)建這些知識需要經(jīng)驗和對于PostgreSQL中索引工作方式的

    理解。在大部分情況下,一個部分索引相對于一個普通索引的優(yōu)勢很小。

    關(guān)于部分索引的更多信息可以在[ston89b]、[olson93]和[seshadri95]中找到

    只用索引的掃描和覆蓋索引

    操作符類和操作符族

    索引和排序規(guī)則

    檢查索引使用

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。