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

歡迎訪問 生活随笔!

生活随笔

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

数据库

mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...

發(fā)布時間:2023/12/15 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在本文中,我們將探討如何通過使用Explain和Analyze來分析慢查詢,以及使用索引來修改和增強查詢時間來解決慢查詢。

Postgres支持在表上使用各種索引,以加快查詢速度。

多列索引

多列B樹索引可以與涉及索引的列的任意子集的查詢條件下使用。當(dāng)(最左邊)列有約束時,此索引最有效。確切的規(guī)則是,前導(dǎo)列上的相等約束,再加上第一列上沒有相等約束的任何不相等約束,都將用于限制掃描的索引部分。

Cover索引

包含查詢所需的所有列的索引,該索引位于select語句中。

唯一索引

唯一索引是用于強制列值的唯一性或一個以上列的組合值的唯一性的索引。

關(guān)于索引的最被誤解的概念之一是了解在哪里使用主鍵,唯一約束或唯一索引。讓我們使用一個問題來理解這一點:

問題陳述

我們要求沒有重復(fù)數(shù)據(jù)的最高性能。哪種方法更好?主鍵,唯一約束或唯一索引?

解決方案

注意:多個空值不相等,因此它們不被視為重復(fù)記錄。

  • 當(dāng)表中定義了主鍵和唯一約束時,Postgres會在表中自動創(chuàng)建唯一索引。這樣,創(chuàng)建唯一約束將是多余的,并且不必要地創(chuàng)建索引會降低Postgres的性能。根據(jù)Postgres產(chǎn)品團(tuán)隊的建議,在表上創(chuàng)建唯一約束,然后就無需在這些列上創(chuàng)建唯一索引。
  • Postgres為定義的主鍵本身創(chuàng)建一個索引。
  • 當(dāng)我們創(chuàng)建唯一約束時,Postgres會在后臺自動創(chuàng)建索引。

但是,在某些情況下,甚至索引也無法提高性能。一種這樣的情況是當(dāng)我們進(jìn)行不區(qū)分大小寫的搜索時。讓我們了解的情況下,查詢成本之間的差額區(qū)分大小寫和不區(qū)分大小寫的搜索 我們的計劃表。鑒于我們在該列上有一個索引scheme_name。

EXPLAIN ANALYSE SELECT * FROM schemes where scheme_name = 'weekend_scheme'

查詢計劃| 在方案上使用idx_scheme_name進(jìn)行索引掃描(成本= 0.28..8.29行= 1寬度= 384)
計劃時間:0.155 ms
執(zhí)行時間:0.063ms

EXPLAIN ANALYSE SELECT * FROM schemes where lower(scheme_name) = 'weekend_scheme'

查詢計劃| 對方案進(jìn)行Seq掃描(成本= 0.00..69.00行= 5寬度= 384)
過濾器:(lower((scheme_name):: text)='weekend_scheme':: text)
被過濾器刪除的行:999
規(guī)劃時間:0.119 ms
執(zhí)行時間:0.721ms

即使我們在處創(chuàng)建了索引scheme_name,該函數(shù)lower也會降低性能,因為它會付出額外的努力將所有的值轉(zhuǎn)換scheme_table為小寫。

不使用索引(盡管已定義)的情況。

  • LIKE ‘%scheme’永遠(yuǎn)不會使用索引,但LIKE ‘scheme%’可能會使用索引。
  • where子句中使用的大寫/小寫函數(shù)。

因此,無論何時我們想在where子句中使用函數(shù),我們都可以通過以下方式創(chuàng)建索引來優(yōu)化查詢。CREATE INDEX idx_scheme_name ON schemes (lower(scheme_name))

EXPLAIN ANALYSE SELECT * FROM schemes where lower(scheme_name) = 'weekend_scheme'

查詢計劃| 方案上的位圖堆掃描((cost = 4.32..19.83行= 5寬度= 384))
重新檢查條件:(較低((scheme_name):: text)='weekend_scheme':: text)
對塊:精確= 1
位圖掃描在方案上((cost = 0.00..4.32行= 5寬度= 0))
索引條件:(較低((scheme_name):: text)='weekend_scheme':: text)
計劃時間:1.784 ms
執(zhí)行時間:0.079 ms

部分指數(shù)

Postgres支持在表的行子集上建立索引(稱為部分索引)。 如果我們要重復(fù)分析與給定WHERE子句匹配的行,這通常是索引數(shù)據(jù)的最佳方法。讓我們看看如何使用部分索引來增強Postgres的性能。

問題陳述

我們要返回所有應(yīng)該在上午11:00之前運行的方案。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time < '10:00:00'

查詢計劃| 對方案進(jìn)行Seq掃描(成本= 0.00..66.50行= 9寬度= 23)
過濾器:(start_time 過濾器刪除的行:991
規(guī)劃時間:0.082 ms
執(zhí)行時間:0.226ms

我們可以在start_time列上創(chuàng)建索引,但是假設(shè)我們有一個龐大的數(shù)據(jù)庫,這對于插入,更新和刪除可能不是最佳選擇。因此,我們創(chuàng)建一個帶有條件的索引。當(dāng)我們從選擇查詢中知道需要什么時,將使用這種索引。假設(shè)我們對所有在10:00:00之前啟動的方案進(jìn)行了大量閱讀,而在以后啟動時則閱讀不多。
CREATE INDEX idx_scheme_name ON schemes start_time WHERE start_time < '11:00:00'

EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time < '10:00:00'

查詢計劃| 方案上的位圖堆掃描((cost = 4.21..29.30行= 9寬度= 23))
重新檢查條件:(start_time 對塊:精確= 8
方案上的位圖索引掃描((cost = 0.00..4.21行= 9寬度= 0))
索引條件:(start_time 計劃時間:1.729 ms
執(zhí)行時間:0.075 ms

這樣可以將執(zhí)行時間從減少0.226到0.075。

讓我們確認(rèn)我們沒有start_time為上午11:00之后的所有方案建立索引。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time >'12:00:00'

查詢計劃| 對方案進(jìn)行Seq掃描(成本= 0.00..66.50行= 6寬度= 23)
篩選器:(start_time 篩選器刪除的行:993
規(guī)劃時間:0.101 ms
執(zhí)行時間:0.228ms

這證明方案表中的部分?jǐn)?shù)據(jù)已編制索引,其余數(shù)據(jù)未編制索引。我們的索引大小非常小,易于維護(hù),有助于維護(hù)重新索引的任務(wù)。

聯(lián)接查詢計劃

優(yōu)化器需要選擇正確的連接時,有在SELECT語句要加入多個表的算法。Postgres根據(jù)我們使用的聯(lián)接類型使用3種不同的聯(lián)接算法。

嵌套循環(huán):在這里,計劃者可以對第一個表中的每個元素使用順序掃描或索引掃描。當(dāng)?shù)诙€表較小時,計劃程序?qū)⑹褂庙樞驋呙琛T陧樞驋呙韬退饕龗呙柚g進(jìn)行選擇的基本邏輯也適用于此。哈希聯(lián)接:在此算法中,計劃程序在聯(lián)接鍵上創(chuàng)建較小表的哈希表。然后掃描較大的表,在哈希表中搜索滿足連接條件的行。首先,這需要大量內(nèi)存才能存儲哈希表。合并聯(lián)接:這類似于合并排序算法。計劃者在這里對兩個要聯(lián)接的表進(jìn)行排序。然后并行掃描這些表以找到匹配的值。

EXPLAIN SELECT schemes.rules FROM scheme_rules JOIN schemes ON (scheme_rules.scheme_id = schemes.id ) where scheme_name = 'weekend_scheme';

生產(chǎn)環(huán)境中索引的缺點

查找未使用的索引

在大型生產(chǎn)環(huán)境中,建議使用未使用的索引,因為索引會占用內(nèi)存。Postgres Wiki頁面詳細(xì)介紹了如何找到索引摘要,重復(fù)索引和索引大小。

CREATE / DROP索引與CREATE / DROP索引并發(fā)

在大型數(shù)據(jù)庫中創(chuàng)建和刪除索引可能要花費數(shù)小時甚至數(shù)天,并且該CREATE INDEX命令會阻止對表的所有寫操作(它不會阻止讀操作,但這仍然不理想)。

但是,與并發(fā)創(chuàng)建的索引CREATE INDEX CONCURRENT不會獲得針對寫入的鎖定。在同時創(chuàng)建索引時,Postgres首先掃描表以建立索引,然后再次運行索引以查找自第一遍以來要添加的內(nèi)容。

同時創(chuàng)建索引也有一個缺點。如果在此過程中出現(xiàn)問題,它不會回滾,并留下無效的索引。可以使用以下查詢找到無效的索引。

SELECT * FROM pg_class,pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;

重建索引

REINDEX使用存儲在索引表中的數(shù)據(jù)重建索引,從而替換索引的舊副本。如果我們懷疑表上的索引損壞,則可以使用REINDEX INDEX或來重建該索引或表上的所有索引。REINDEX TABLE

REINDEX與刪除索引和重新創(chuàng)建索引相似,因為索引內(nèi)容是從頭開始重建的。但是,鎖定注意事項卻大不相同。REINDEX鎖定對索引的父表的寫入但不對其進(jìn)行讀取。它還對正在處理的特定索引采取排他鎖,這將阻止嘗試使用該索引的讀取。

另一個選擇是同時刪除索引并再次創(chuàng)建。

結(jié)論

這篇文章旨在概述Postgres如何查詢數(shù)據(jù)庫。通過更好地理解查詢計劃并仔細(xì)采取措施(主要是通過索引),我們可以從Postgres數(shù)據(jù)庫中獲得最佳性能。

還有其他提高查詢性能的方法,但我們會將其保存在以后的文章中。

總結(jié)

以上是生活随笔為你收集整理的mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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