mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...
在本文中,我們將探討如何通過使用Explain和Analyze來分析慢查詢,以及使用索引來修改和增強查詢時間來解決慢查詢。
Postgres支持在表上使用各種索引,以加快查詢速度。
多列索引
多列B樹索引可以與涉及索引的列的任意子集的查詢條件下使用。當(最左邊)列有約束時,此索引最有效。確切的規則是,前導列上的相等約束,再加上第一列上沒有相等約束的任何不相等約束,都將用于限制掃描的索引部分。
Cover索引
包含查詢所需的所有列的索引,該索引位于select語句中。
唯一索引
唯一索引是用于強制列值的唯一性或一個以上列的組合值的唯一性的索引。
關于索引的最被誤解的概念之一是了解在哪里使用主鍵,唯一約束或唯一索引。讓我們使用一個問題來理解這一點:
問題陳述
我們要求沒有重復數據的最高性能。哪種方法更好?主鍵,唯一約束或唯一索引?
解決方案
注意:多個空值不相等,因此它們不被視為重復記錄。
- 當表中定義了主鍵和唯一約束時,Postgres會在表中自動創建唯一索引。這樣,創建唯一約束將是多余的,并且不必要地創建索引會降低Postgres的性能。根據Postgres產品團隊的建議,在表上創建唯一約束,然后就無需在這些列上創建唯一索引。
- Postgres為定義的主鍵本身創建一個索引。
- 當我們創建唯一約束時,Postgres會在后臺自動創建索引。
但是,在某些情況下,甚至索引也無法提高性能。一種這樣的情況是當我們進行不區分大小寫的搜索時。讓我們了解的情況下,查詢成本之間的差額區分大小寫和不區分大小寫的搜索 我們的計劃表。鑒于我們在該列上有一個索引scheme_name。
EXPLAIN ANALYSE SELECT * FROM schemes where scheme_name = 'weekend_scheme'
查詢計劃| 在方案上使用idx_scheme_name進行索引掃描(成本= 0.28..8.29行= 1寬度= 384)
計劃時間:0.155 ms
執行時間:0.063ms
EXPLAIN ANALYSE SELECT * FROM schemes where lower(scheme_name) = 'weekend_scheme'
查詢計劃| 對方案進行Seq掃描(成本= 0.00..69.00行= 5寬度= 384)
過濾器:(lower((scheme_name):: text)='weekend_scheme':: text)
被過濾器刪除的行:999
規劃時間:0.119 ms
執行時間:0.721ms
即使我們在處創建了索引scheme_name,該函數lower也會降低性能,因為它會付出額外的努力將所有的值轉換scheme_table為小寫。
不使用索引(盡管已定義)的情況。
- LIKE ‘%scheme’永遠不會使用索引,但LIKE ‘scheme%’可能會使用索引。
- where子句中使用的大寫/小寫函數。
因此,無論何時我們想在where子句中使用函數,我們都可以通過以下方式創建索引來優化查詢。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
執行時間:0.079 ms
部分指數
Postgres支持在表的行子集上建立索引(稱為部分索引)。 如果我們要重復分析與給定WHERE子句匹配的行,這通常是索引數據的最佳方法。讓我們看看如何使用部分索引來增強Postgres的性能。
問題陳述
我們要返回所有應該在上午11:00之前運行的方案。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time < '10:00:00'
查詢計劃| 對方案進行Seq掃描(成本= 0.00..66.50行= 9寬度= 23)
過濾器:(start_time 過濾器刪除的行:991
規劃時間:0.082 ms
執行時間:0.226ms
我們可以在start_time列上創建索引,但是假設我們有一個龐大的數據庫,這對于插入,更新和刪除可能不是最佳選擇。因此,我們創建一個帶有條件的索引。當我們從選擇查詢中知道需要什么時,將使用這種索引。假設我們對所有在10:00:00之前啟動的方案進行了大量閱讀,而在以后啟動時則閱讀不多。
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
執行時間:0.075 ms
這樣可以將執行時間從減少0.226到0.075。
讓我們確認我們沒有start_time為上午11:00之后的所有方案建立索引。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time >'12:00:00'
查詢計劃| 對方案進行Seq掃描(成本= 0.00..66.50行= 6寬度= 23)
篩選器:(start_time 篩選器刪除的行:993
規劃時間:0.101 ms
執行時間:0.228ms
這證明方案表中的部分數據已編制索引,其余數據未編制索引。我們的索引大小非常小,易于維護,有助于維護重新索引的任務。
聯接查詢計劃
優化器需要選擇正確的連接時,有在SELECT語句要加入多個表的算法。Postgres根據我們使用的聯接類型使用3種不同的聯接算法。
嵌套循環:在這里,計劃者可以對第一個表中的每個元素使用順序掃描或索引掃描。當第二個表較小時,計劃程序將使用順序掃描。在順序掃描和索引掃描之間進行選擇的基本邏輯也適用于此。哈希聯接:在此算法中,計劃程序在聯接鍵上創建較小表的哈希表。然后掃描較大的表,在哈希表中搜索滿足連接條件的行。首先,這需要大量內存才能存儲哈希表。合并聯接:這類似于合并排序算法。計劃者在這里對兩個要聯接的表進行排序。然后并行掃描這些表以找到匹配的值。
EXPLAIN SELECT schemes.rules FROM scheme_rules JOIN schemes ON (scheme_rules.scheme_id = schemes.id ) where scheme_name = 'weekend_scheme';
生產環境中索引的缺點
查找未使用的索引
在大型生產環境中,建議使用未使用的索引,因為索引會占用內存。Postgres Wiki頁面詳細介紹了如何找到索引摘要,重復索引和索引大小。
CREATE / DROP索引與CREATE / DROP索引并發
在大型數據庫中創建和刪除索引可能要花費數小時甚至數天,并且該CREATE INDEX命令會阻止對表的所有寫操作(它不會阻止讀操作,但這仍然不理想)。
但是,與并發創建的索引CREATE INDEX CONCURRENT不會獲得針對寫入的鎖定。在同時創建索引時,Postgres首先掃描表以建立索引,然后再次運行索引以查找自第一遍以來要添加的內容。
同時創建索引也有一個缺點。如果在此過程中出現問題,它不會回滾,并留下無效的索引。可以使用以下查詢找到無效的索引。
SELECT * FROM pg_class,pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;重建索引
REINDEX使用存儲在索引表中的數據重建索引,從而替換索引的舊副本。如果我們懷疑表上的索引損壞,則可以使用REINDEX INDEX或來重建該索引或表上的所有索引。REINDEX TABLE
REINDEX與刪除索引和重新創建索引相似,因為索引內容是從頭開始重建的。但是,鎖定注意事項卻大不相同。REINDEX鎖定對索引的父表的寫入但不對其進行讀取。它還對正在處理的特定索引采取排他鎖,這將阻止嘗試使用該索引的讀取。
另一個選擇是同時刪除索引并再次創建。
結論
這篇文章旨在概述Postgres如何查詢數據庫。通過更好地理解查詢計劃并仔細采取措施(主要是通過索引),我們可以從Postgres數據庫中獲得最佳性能。
還有其他提高查詢性能的方法,但我們會將其保存在以后的文章中。
總結
以上是生活随笔為你收集整理的mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的世界窗帘怎么做(汉典我字的基本解释)
- 下一篇: 我的世界怎么造龙(汉典我字的基本解释)