PG裡常見的欄位有索引但未使用索引的原因
對於一個系統而言,穩定性、效能、安全是很重要的幾點。運維的一些工作也是圍繞著這些去做。對於某些時候,業務層可能會向資料庫層提出種種質疑:為什麼資料庫這麼慢?為什麼資料庫掛了?為什麼我這麼用,SQL走不了索引?諸如此類。
其實對於瞭解資料庫和運維的大家都知道,這些使用關係型資料庫的應用系統,SQL語句的好壞會直接影響系統的效能,很多系統效能很差最後發現都是因為SQL寫得很爛的緣故。
有時候可能一條SQL在業務設計之初就存在問題,每次跑的時候每次都走全表掃描,耗費大量的系統資源,亦或者在業務執行到現在的期間內資料量猛增,資料量導致SQL的執行結果遠遠大於原來的,導致業務受影響。甚至設計的一些SQL,他本身存在過多的複雜操作,各種聚合、連線加到一起,這一條SQL跑起來可能就會造成很大的資源佔用,甚至嚴重導致資料庫的記憶體溢位、資料庫當機等等。或者業務層並不瞭解各種索引的實際原理,並不能在合適的場景選擇合適的索引,這可能導致,原本SQL查詢對應的想要他走索引的欄位,沒走索引。從而影響效能。
對所有的關係型資料庫而言,最佳化器無疑是其中最核心的部分,因為最佳化器負責解析SQL,而我們又都是透過SQL來訪問儲存在關係型資料庫中的資料的。所以最佳化器的好壞會直接決定該關係型資料庫的強弱。
通常來說,最佳化器分為兩種,一種是CBO,即Cost-BasedOptimizer 的縮寫,直譯過來就是“ 基於成本的最佳化器”。一種是RBO,是Rule-BasedOptimizer 的縮寫,直譯過來就是“基於規則的最佳化器”。
在得到最終的執行計劃時,RBO會根據一組內建的規則,去選擇執行計劃,這就導致了RBO選擇的執行計劃可能不是最優的,不是執行時間最短的,因為他只根據對應的規則去選取執行計劃。而CBO所用的判斷原則為成本,CBO會從目標SQL諸多可能的執行路徑中選擇成本值最小的一條來作為其執行計劃。在CBO模式下,由於開銷都是估算值,所以準確性嚴重依賴於統計資訊,如果統計資訊越接近表的真實資料時,CBO最佳化器的估算值則越準確,產生的執行計劃也更佳準確。但是如果統計資訊和實際表資料差的很遠,那麼可能透過CBO得出的執行計劃也可能不是最優的,這個時候就有可能因為這條錯誤的執行計劃,引起效能問題或者相關故障。而目前主流資料庫均採用CBO模式,因為相較於RBO來說,CBO還是更加傾向於得到這個對的執行計劃的。
PostgreSQL資料庫裡也是採用的這種CBO的最佳化器。下面這部分,我就針對上面所說的PostgreSQL裡常見的欄位有索引但沒有使用索引的現象,進行了幾個舉例,供大家參考。對於如下的幾個案例的執行計劃選擇,其實歸根到最後,都是基於CBO得出的代價最小的,或是影響了CBO的判斷得到的最後的結果。
一、索引列存在多個or連線
二、資料量太小
三、選擇性不好
四、查詢條件模糊
五、表的一個列上有重複索引
六、最佳化器選項關閉了索引掃描
七、統計資訊不準確
八、Hints影響執行計劃
九、查詢條件中使用函式
十、查詢條件中有不等於運運算元
一、索引列存在多個or連線
當查詢條件中存在多個OR連線時,PostgreSQL需要將所有條件的結果集進行合併,而這個合併操作可能會導致索引失效。
1.模擬環境
postgres=# create table idxidx as select * from pg_class; SELECT 445 postgres=# create index idx_11 on idxidx(oid); CREATE INDEX
2.測試情況
一個or連線兩個索引列(走索引)
postgres=# explain analyze select oid,relname,relnamespace from idxidx where oid =17726 or oid=17743; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on idxidx (cost=8.56..14.14 rows=2 width=72) (actual time=0.018..0.019 rows=1 loops=1) Recheck Cond: ((oid = '17726'::oid) OR (oid = '17743'::oid)) Heap Blocks: exact=1 -> BitmapOr (cost=8.56..8.56 rows=2 width=0) (actual time=0.012..0.013 rows=0 loops=1) -> Bitmap Index Scan on idx_11 (cost=0.00..4.28 rows=1 width=0) (actual time=0.011..0.011 rows=1 loops=1) Index Cond: (oid = '17726'::oid) -> Bitmap Index Scan on idx_11 (cost=0.00..4.28 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1) Index Cond: (oid = '17743'::oid) Planning Time: 0.061 ms Execution Time: 0.038 ms (10 rows)
兩個or連線三個索引列(走全表掃描)
postgres=# explain analyze select oid,relname,relnamespace from idxidx where oid =17726 or oid=17765 or oid=17743; QUERY PLAN -------------------------------------------------------------------------------------------------- Seq Scan on idxidx (cost=0.00..19.79 rows=3 width=72) (actual time=0.012..0.064 rows=1 loops=1) Filter: ((oid = '17726'::oid) OR (oid = '17765'::oid) OR (oid = '17743'::oid)) Rows Removed by Filter: 444 Planning Time: 0.059 ms Execution Time: 0.079 ms (5 rows)
要避免這種情況,可以嘗試對查詢條件進行重寫,例如使用UNION ALL連線多個查詢條件,例如如如下這種方式
postgres=# explain analyze select oid,relname,relnamespace from idxidx where oid =17726 union all select oid,relname,relnamespace from idxidx where oid=17765 union all select oid,relname,relnamespace from idxidx where oid=17743; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- Append (cost=0.27..24.92 rows=3 width=72) (actual time=0.041..0.046 rows=1 loops=1) -> Index Scan using idx_11 on idxidx (cost=0.27..8.29 rows=1 width=72) (actual time=0.041..0.042 rows=1 loops=1) Index Cond: (oid = '17726'::oid) -> Index Scan using idx_11 on idxidx idxidx_1 (cost=0.27..8.29 rows=1 width=72) (actual time=0.002..0.002 rows=0 loops=1) Index Cond: (oid = '17765'::oid) -> Index Scan using idx_11 on idxidx idxidx_2 (cost=0.27..8.29 rows=1 width=72) (actual time=0.001..0.001 rows=0 loops=1) Index Cond: (oid = '17743'::oid) Planning Time: 0.169 ms Execution Time: 0.082 ms (9 rows)
二、資料量太小
對於非常小的表或者索引,使用索引可能會比全表掃描更慢。這是因為使用索引需要進行額外的 I/O 操作,而這些操作可能比直接掃描表更慢。
1.模擬環境
postgres=# create table tn(id int,name varchar); CREATE TABLE postgres=# insert into tn values(1,'ysl'); INSERT 0 1 postgres=# insert into tn values(2,'ysl'); INSERT 0 1 postgres=# insert into tn values(2,'ysll'); INSERT 0 1 postgres=# insert into tn values(2,'ysll'); INSERT 0 1 postgres=# create index idx_tn on tn(id); CREATE INDEX postgres=# \d tn Table "public.tn" Column | Type | Collation | Nullable | Default --------+-------------------+-----------+----------+--------- id | integer | | | name | character varying | | | Indexes: "idx_tn" btree (id) postgres=# select * from tn; id | name ----+------ 1 | ysl 2 | ysl 2 | ysll 2 | ysll (4 rows)
2.測試
postgres=# explain analyze select * from tn where id=2; QUERY PLAN --------------------------------------------------------------------------------------------- Seq Scan on tn (cost=0.00..1.05 rows=1 width=36) (actual time=0.007..0.007 rows=3 loops=1) Filter: (id = 2) Rows Removed by Filter: 1 Planning Time: 0.053 ms Execution Time: 0.021 ms (5 rows) postgres=# explain analyze select * from tn where id=1; QUERY PLAN --------------------------------------------------------------------------------------------- Seq Scan on tn (cost=0.00..1.05 rows=1 width=36) (actual time=0.011..0.012 rows=1 loops=1) Filter: (id = 1) Rows Removed by Filter: 3 Planning Time: 0.057 ms Execution Time: 0.026 ms (5 rows)
三.選擇性不好
如果索引列中有大量重複的資料,或者一個欄位全是一個值,這個時候,索引可能並不能發揮它的作用,起到加快檢索的作用,因為這個索引並不能顯著地減少需要掃描的行數,所以計算的代價可能遠遠大於走別的執行計劃的代價。
基數:資料庫基數是指資料庫中不同值的數量
select count(distinct column_name) from table_name;
選擇性:基數和總行數的比值再乘以100%就是某個列的選擇性。
select count(distinct column_name) /count(column_name)* 100% from table_name;
1.模擬環境
postgres=# create table tb_t1 as select * from pg_class; SELECT 465 postgres=# create index idx_tb_t1 on tb_t1(oid); CREATE INDEX
2.測試
可以看到,原本oid這一列,選擇性較好,分佈較均勻的時候,可以正常使用到索引。而選擇性不好的情況下,則
postgres=# explain analyze select * from tb_t1 where oid=17726; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Bitmap Heap Scan on tb_t1 (cost=4.29..9.86 rows=2 width=236) (actual time=0.024..0.025 rows=1 loops=1) Recheck Cond: (oid = '17726'::oid) Heap Blocks: exact=1 -> Bitmap Index Scan on idx_tb_t1 (cost=0.00..4.29 rows=2 width=0) (actual time=0.021..0.021 rows=1 loops=1) Index Cond: (oid = '17726'::oid) Planning Time: 0.220 ms Execution Time: 0.059 ms (7 rows) postgres=# update tb_t1 set oid=1; UPDATE 465 postgres=# reindex index idx_tb_t1; REINDEX postgres=# explain analyze select * from tb_t1 where oid=1; QUERY PLAN ------------------------------------------------------------------------------------------------------ Seq Scan on tb_t1 (cost=0.00..29.81 rows=465 width=274) (actual time=0.013..0.080 rows=465 loops=1) Filter: (oid = '1'::oid) Planning Time: 0.344 ms Execution Time: 0.111 ms (4 rows)
上邊的這個例子,在我做完update後,列的基數是select count(distinct oid) from tb_t1;也就是1。而選擇性是select count(distinct oid)/count(oid)* 100% from tb_t1;也就是1/465 *100% 選擇性特別低。索引不能起到減少掃描的行數,反而在原本的基礎上多了回表的動作,代價就增多了。因此CBO沒有選擇走這個索引的執行計劃。
四、查詢條件模糊
如果查詢條件模糊,例如使用了不等於(<>)、LIKE等運運算元或者使用了函式等,那麼索引可能無法被使用。
因為正常情況下,等於(=)運運算元可以直接利用B-tree或雜湊索引進行查詢。這是因為,這些運運算元只需要在索引樹中查詢與給定值相等的項,就可以快速地定位到符合條件的記錄。
而不等於(<>)運運算元則需要查詢所有不符合條件的記錄,這會導致需要遍歷整個索引樹來找到匹配的記錄,因此使用索引的成本比全表掃描更高。
LIKE運運算元也可能導致不使用索引。這是因為,LIKE運運算元通常需要執行模糊匹配,即查詢包含你給的關鍵字的記錄。雖然可以使用B-tree索引進行模糊匹配,但是如果模式以萬用字元開頭(例如’%abc’),則索引將不會被使用,因為這種情況下需要遍歷整個索引樹來查詢符合條件的記錄。
這兩種方式在列上有索引的時候,都是不能顯著地減少需要掃描的行數。甚至加大SQL執行的代價,因此可能上邊的索引不會被CBO選擇為最後最優的執行計劃。
1.模擬環境
postgres=# create table tb_l1 as select * from pg_class; SELECT 465 postgres=# create index idx_tb_l1 on tb_l1(oid); CREATE INDEX
2.測試
postgres=# explain analyze select * from tb_l1 where oid=17726; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Index Scan using idx_tb_l1 on tb_l1 (cost=0.27..8.29 rows=1 width=274) (actual time=0.029..0.030 rows=1 loops=1) Index Cond: (oid = '17726'::oid) Planning Time: 0.473 ms Execution Time: 0.083 ms (4 rows) postgres=# explain analyze select * from tb_l1 where oid<>17726; QUERY PLAN ------------------------------------------------------------------------------------------------------ Seq Scan on tb_l1 (cost=0.00..17.81 rows=464 width=274) (actual time=0.007..0.103 rows=464 loops=1) Filter: (oid <> '17726'::oid) Rows Removed by Filter: 1 Planning Time: 0.069 ms Execution Time: 0.132 ms (5 rows)
五、表的一個列上有重複索引
在PostgreSQL裡,是允許在一列上建立多個索引的,也就是如下這種方式,是不會報錯說索引重複的,這也就導致了,使用過程中表上可能存在多餘的重複索引,索引不會全部被使用到,而且可能引起效能問題。
postgres=# create index idx_tb_l1 on tb_l1(oid); CREATE INDEX postgres=# create index idx_tb_l2 on tb_l1(oid); CREATE INDEX
1.模擬環境
postgres=# create table tb_l1 as select * from pg_class; SELECT 465 postgres=# create index idx_tb_l1 on tb_l1(oid); CREATE INDEX postgres=# create index idx_tb_l2 on tb_l1(oid); CREATE INDEX postgres=# \d tb_l1 Table "public.tb_l1" Column | Type | Collation | Nullable | Default ---------------------+--------------+-----------+----------+--------- oid | oid | | | relname | name | | | relnamespace | oid | | | reltype | oid | | | reloftype | oid | | | relowner | oid | | | ... ... ... ... Indexes: "idx_tb_l1" btree (oid) "idx_tb_l2" btree (oid)
2.測試
postgres=# explain analyze select * from tb_l1 where oid=17726; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Index Scan using idx_tb_l2 on tb_l1 (cost=0.27..8.29 rows=1 width=274) (actual time=0.025..0.025 rows=1 loops=1) Index Cond: (oid = '17726'::oid) Planning Time: 0.364 ms Execution Time: 0.043 ms (4 rows)
測試可以看到,在一個表的同一列上的兩個索引其實作用是一樣的,僅僅名字不一樣,屬於重複索引,這種情況下,就算用到索引,同一時刻也就會使用到一個索引。
使用如下的SQL可以找到資料庫裡的重複索引,可以定期巡檢的時候進行檢查,並在確認後合理最佳化掉重複的索引
SELECT indrelid :: regclass AS table_name, array_agg(indexrelid :: regclass) AS indexes FROM pg_index GROUP BY indrelid, indkey HAVING COUNT(*) > 1;
一個執行的結果如下所示:
postgres=# SELECT indrelid :: regclass AS table_name, array_agg(indexrelid :: regclass) AS indexes FROM pg_index GROUP BY indrelid, indkey HAVING COUNT(*) > 1; table_name | indexes ------------+----------------------- tb_l1 | {idx_tb_l1,idx_tb_l2} t1 | {ind1,idx2} (2 rows) postgres=# \di+ idx_tb_l1 List of relations Schema | Name | Type | Owner | Table | Persistence | Access method | Size | Description --------+-----------+-------+---------+-------+-------------+---------------+-------+------------- public | idx_tb_l1 | index | xmaster | tb_l1 | permanent | btree | 32 kB | (1 row) postgres=# \di+ idx_tb_l2 List of relations Schema | Name | Type | Owner | Table | Persistence | Access method | Size | Description --------+-----------+-------+---------+-------+-------------+---------------+-------+------------- public | idx_tb_l2 | index | xmaster | tb_l1 | permanent | btree | 32 kB | (1 row)
六、最佳化器選項關閉了索引掃描
PostgreSQL裡有著很多的可以影響最佳化器的引數,例如enable_indexscan,enable_bitmapscan,enable_hashjoin,enable_sort等等,這些引數可以在session,使用者,資料庫級別進行設定。可以透過設定這些引數的值,來改變相關SQL執行時的執行計劃。但是需要注意的是,為了個別的SQL,去盲目改變這些引數的值,往往是得不償失的,操作的時候需要嚴謹並且仔細考慮,否則,這些型別的引數的改變,對於資料庫的效能影響可能是巨大的。
1.模擬環境
postgres=# create table tb_l1 as select * from pg_class; SELECT 465 postgres=# create index idx_tb_l1 on tb_l1(oid); CREATE INDEX
2.測試
開啟了對應最佳化器選項
postgres=# show enable_indexscan ; enable_indexscan ------------------ on (1 row) postgres=# show enable_bitmapscan ; enable_bitmapscan ------------------- on (1 row) postgres=# explain analyze select * from tb_l1 where oid=17721; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Index Scan using idx_tb_l2 on tb_l1 (cost=0.27..8.29 rows=1 width=274) (actual time=0.017..0.018 rows=1 loops=1) Index Cond: (oid = '17721'::oid) Planning Time: 0.088 ms Execution Time: 0.038 ms (4 rows)
關閉對應的最佳化器選項,可以看到CBO受到設定的引數的影響,選擇了seq scan的執行計劃,而沒有用到欄位上的索引。
postgres=# set enable_indexscan=off; SET postgres=# set enable_bitmapscan=off; SET postgres=# explain analyze select * from tb_l1 where oid=17721; QUERY PLAN -------------------------------------------------------------------------------------------------- Seq Scan on tb_l1 (cost=0.00..17.81 rows=1 width=274) (actual time=0.024..0.137 rows=1 loops=1) Filter: (oid = '17721'::oid) Rows Removed by Filter: 464 Planning Time: 0.079 ms Execution Time: 0.192 ms (5 rows)
七、統計資訊不準確
因為CBO本身是基於代價的最佳化器,而計算代價要根據統計資訊去做計算,統計資訊不準確,得到的執行計劃可能不是最優,這一點不做具體的舉例。
八、Hints影響執行計劃
PostgreSQL資料庫裡有著像ORACLE裡類似的Hints功能,即pg_hint_plan工具,用Hints能夠改變sql語句的執行計劃,hint就是最佳化器的一種指示。雖然功能上和效果是類似的,但是PostgreSQL和ORACLE的Hints並不完全一致的,例如全表掃描等的關鍵字是不同的,需要進行區分。
1、準備環境
資料庫需安裝pg_hint_plan外掛
postgres=# create table test_hint(id int,c varchar(100)); CREATE TABLE postgres=# insert into test_hint select i,'test'||i from generate_series(1,10000) i; INSERT 0 10000 postgres=# create index idx_test_hint_id on test_hint(id); CREATE INDEX
2、測試
預設會走索引掃描,但是使用了hint,讓其走了seqscan,沒有使用到對應的欄位上的索引。
postgres=# explain analyze select * from test_hint where id=10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- Index Scan using idx_test_hint_id on test_hint (cost=0.29..8.30 rows=1 width=12) (actual time=0.008..0.008 rows=1 loops=1) Index Cond: (id = 10) Planning Time: 0.111 ms Execution Time: 0.024 ms (4 rows) postgres=# explain analyze select /*+seqscan(t) */ * from test_hint t where id=10; QUERY PLAN -------------------------------------------------------------------------------------------------------- Seq Scan on test_hint t (cost=0.00..180.00 rows=1 width=12) (actual time=0.022..2.691 rows=1 loops=1) Filter: (id = 10) Rows Removed by Filter: 9999 Planning Time: 0.311 ms Execution Time: 2.712 ms (5 rows)
九、查詢條件中使用函式
當查詢條件中包含函式呼叫時,PostgreSQL裡可能無法使用索引,因為它需要對所有資料進行計算,而不是隻計算索引值。
1、準備環境
postgres=# CREATE TABLE test_table ( postgres(# id SERIAL PRIMARY KEY, postgres(# name TEXT, postgres(# age INTEGER postgres(# ); CREATE TABLE postgres=# postgres=# CREATE INDEX age_index ON test_table(age); CREATE INDEX postgres=# INSERT INTO test_table (name, age) VALUES postgres-# ('Alice', 25), postgres-# ('Bob', 30), postgres-# ('Charlie', 35), postgres-# ('David', 40), postgres-# ('Eve', 45), postgres-# ('Frank', 50); INSERT 0 6 postgres=# CREATE OR REPLACE FUNCTION search_age(p_age INTEGER) RETURNS SETOF test_table AS $$ postgres$# BEGIN postgres$# RETURN QUERY SELECT * FROM test_table WHERE age > p_age; postgres$# END; postgres$# $$ LANGUAGE plpgsql; CREATE FUNCTION
2、測試
可以看到,當查詢條件中包含函式呼叫時,沒有使用到索引,而是使用了一個 Function Scan。這個Function Scan也是一種特殊的掃描方式,是從函式中獲取資料。PostgreSQL會呼叫指定的函式來處理查詢結果,並且會為函式的輸出結果建立一個虛擬的關係表,以便後續的節點可以使用這個關係表繼續執行查詢。
postgres=# EXPLAIN ANALYZE SELECT * FROM test_table WHERE age > 35; QUERY PLAN -------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on test_table (cost=7.25..22.25 rows=400 width=40) (actual time=0.008..0.009 rows=3 loops=1) Recheck Cond: (age > 35) Heap Blocks: exact=1 -> Bitmap Index Scan on age_index (cost=0.00..7.15 rows=400 width=0) (actual time=0.004..0.004 rows=3 loops=1) Index Cond: (age > 35) Planning Time: 0.075 ms Execution Time: 0.027 ms (7 rows) postgres=# EXPLAIN ANALYZE SELECT * FROM search_age(35); QUERY PLAN -------------------------------------------------------------------------------------------------------------- Function Scan on search_age (cost=0.25..10.25 rows=1000 width=40) (actual time=0.147..0.147 rows=3 loops=1) Planning Time: 0.027 ms Execution Time: 0.162 ms (3 rows)
十、查詢條件中有不等於運運算元
因為在索引掃描期間,不等於運運算元會導致索引中的每一行都需要進行比較,因此需要走全表掃描,不會走索引。
1.環境準備
postgres=# create table tb_l1 as select * from pg_class; SELECT 465 postgres=# create index idx_tb_l1 on tb_l1(oid); CREATE INDEX
2.測試
postgres=# explain analyze select * from tb_l1 where oid<>17721; QUERY PLAN ------------------------------------------------------------------------------------------------------ Seq Scan on tb_l1 (cost=0.00..17.81 rows=464 width=274) (actual time=0.007..0.063 rows=464 loops=1) Filter: (oid <> '17721'::oid) Rows Removed by Filter: 1 Planning Time: 0.064 ms Execution Time: 0.091 ms (5 rows) postgres=# explain analyze select * from tb_l1 where oid =17721; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Index Scan using idx_tb_l2 on tb_l1 (cost=0.27..8.29 rows=1 width=274) (actual time=0.019..0.021 rows=1 loops=1) Index Cond: (oid = '17721'::oid) Planning Time: 0.107 ms Execution Time: 0.051 ms (4 rows) postgres=# explain analyze select * from tb_l1 where oid !=17721; QUERY PLAN ------------------------------------------------------------------------------------------------------ Seq Scan on tb_l1 (cost=0.00..17.81 rows=464 width=274) (actual time=0.012..0.072 rows=464 loops=1) Filter: (oid <> '17721'::oid) Rows Removed by Filter: 1 Planning Time: 0.071 ms Execution Time: 0.102 ms (5 rows)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990629/viewspace-2950123/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 常見的導致PG建立索引慢的原因索引
- SQLServer索引優化(1):對於有order by欄位的建索引策略SQLServer索引優化
- MySQL null值欄位是否使用索引的總結MySqlNull索引
- [20181020]lob欄位的索引段.txt索引
- 常見的索引模型淺析索引模型
- oracle複合索引介紹(多欄位索引)Oracle索引
- MySQL常見索引概念MySql索引
- 怎麼給字串欄位加索引?字串索引
- MySQL 之索引常見內容MySql索引
- MySQL 選錯索引的原因?MySql索引
- 常見Http首部欄位HTTP
- 【INDEX】Oracle 索引常見知識梳理IndexOracle索引
- 外來鍵欄位未建索引引發的死鎖索引
- [20180408]那些函式索引適合欄位的查詢.txt函式索引
- 索引的使用索引
- 盤一盤常見的6種索引失效情況索引
- [20190810]如何索引一個超長欄位.txt索引
- Oracle vs PG 索引資訊Oracle索引
- 使用HTTP代理失敗的常見原因HTTP
- Oracle 計算欄位選擇性 判別列的索引潛力Oracle索引
- 類索引器的老生常談索引
- 使用Elasticsearch的動態索引和索引優化Elasticsearch索引優化
- LevelDB專欄文章索引索引
- C#學習筆記-欄位、屬性、索引器C#筆記索引
- 建立索引後,速度變快原因?以及索引失效總結索引
- 要慎用mysql的enum欄位的原因MySql
- 聯合索引和多個單列索引使用中的索引命中情況及索引建立原則索引
- MySQL 中索引是如何實現的,有哪些型別的索引,如何進行最佳化索引MySql索引型別
- 用Elasticsearch做大規模資料的多欄位、多型別索引檢索Elasticsearch多型型別索引
- PostgreSQL資料庫多列複合索引的欄位順序選擇原理SQL資料庫索引
- [BUG反饋]模型管理 > 欄位管理看不見任何欄位。這表明顯有欄位、!模型
- 主鍵索引 (聚集索引) 和普通索引 (輔助索引) 的區別索引
- 索引使用的基本原則索引
- 關於pcl索引的使用索引
- 監控索引的使用(轉)索引
- MySQL的索引原理及使用MySql索引
- MySQL全文索引的使用MySql索引
- 什麼索引算是好的索引索引