Postgresql

如何改善大桌子上的簡單 = 條件?

  • June 22, 2022

查看以下簡單查詢:

SELECT * FROM "teammgr_team" WHERE ("teammgr_team"."real" = true AND "teammgr_team"."name" = 'abc');

但是時間太長了:

-------------------------------------------------------------------------------------------------------------------
Seq Scan on teammgr_team  (cost=0.00..114772.49 rows=118 width=121) (actual time=24.544..618.185 rows=12 loops=1)
  Filter: ("real" AND ((name)::text = 'abc'::text))
  Rows Removed by Filter: 4752431
Planning time: 0.066 ms
Execution time: 618.217 ms
(5 rows)

我假設因為桌子很大:

 count
---------
4752443
(1 row)

這是表格和相關列:

                                      Table "public.teammgr_team"
       Column        |         Type          |                         Modifiers
----------------------+-----------------------+-----------------------------------------------------------
id                   | integer               | not null default nextval('teammgr_team_id_seq'::regclass)
name                 | character varying(40) | not null

Indexes:
   "teammgr_team_pkey" PRIMARY KEY, btree (id)
   "teammgr_team_club_id" btree (club_id)

我不確定是否建議向字元列添加索引。我會這麼認為,但我對數據庫的了解還不夠。

所以我正在考慮添加一個簡單的索引:

CREATE INDEX teammgr_team_name ON teammgr_team (name);

請記住,這不應該是UNIQUE因為團隊名稱不是唯一的。

  • 添加此索引是否有助於縮短執行時間?
  • 我已經瀏覽了這些文件,但有什麼選擇對我的目標有益嗎?

您的查詢過濾了數百萬行以返回一個充滿值的手。所以,的,添加這個索引將有很大幫助:

CREATE INDEX teammgr_team_name_idx ON teammgr_team (name);

如果您的查詢總是要求teammgr_team."real" = true並且該情況不是表中的常見情況,則部分索引會更好:

CREATE INDEX teammgr_team_name_real_idx ON teammgr_team (name)
WHERE real;

或者也許是一個多列索引

CREATE INDEX teammgr_team_name_real_idx ON teammgr_team (name, real);

但是添加一個布爾列作為索引表達式的好處通常是有限的。在罕見情況下使用部分索引通常更有效。

這一切都取決於確切的數據分佈。而且,可能在典型的寫入模式下:高度易失的列(更新很多)索引成本更高。

除了 1

簡化:

SELECT * FROM teammgr_team WHERE real AND name = 'abc';

WHERE teammgr_team."real" = true只是一種吵鬧的說法WHERE real

除了 2

不要使用基本類型名稱,real如標識符。導致混亂。而“名”也不是個好名字。

引用自:https://dba.stackexchange.com/questions/313606