我已經繼承了一個大的遺留代碼庫,它在django 1.5中運行,我目前的任務是加速一個網站部分,需要加載〜1min。提高查詢速度:簡單選擇與喜歡
我做了應用程序的輪廓,並得到這個:
特別罪魁禍首是以下查詢(剝離爲了簡潔):
SELECT COUNT(*) FROM "entities_entity" WHERE (
"entities_entity"."date_filed" <= '2016-01-21' AND (
UPPER("entities_entity"."entity_city_state_zip"::text) LIKE UPPER('%Atherton%') OR
UPPER("entities_entity"."entity_city_state_zip"::text) LIKE UPPER('%Berkeley%') OR
-- 34 more of these
UPPER("entities_entity"."agent_city_state_zip"::text) LIKE UPPER('%Atherton%') OR
UPPER("entities_entity"."agent_city_state_zip"::text) LIKE UPPER('%Berkeley%') OR
-- 34 more of these
)
)
基本上由上大查詢兩個字段,entity_city_state_zip
和agent_city_state_zip
這是character varying(200) | not null
字段。
查詢是執行兩次(!),同時每次18814.02ms,和一次更換COUNT
的SELECT
佔用額外20216.49
(我要去緩存COUNT
結果)
的這樣的解釋看起來:
Aggregate (cost=175867.33..175867.34 rows=1 width=0) (actual time=17841.502..17841.502 rows=1 loops=1)
-> Seq Scan on entities_entity (cost=0.00..175858.95 rows=3351 width=0) (actual time=0.849..17818.551 rows=145075 loops=1)
Filter: ((date_filed <= '2016-01-21'::date) AND ((upper((entity_city_state_zip)::text) ~~ '%ATHERTON%'::text) OR (upper((entity_city_state_zip)::text) ~~ '%BERKELEY%'::text) (..skipped..) OR (upper((agent_city_state_zip)::text) ~~ '%ATHERTON%'::text) OR (upper((agent_city_state_zip)::text) ~~ '%BERKELEY%'::text) OR (upper((agent_city_state_zip)::text) ~~ '%BURLINGAME%'::text)))
Rows Removed by Filter: 310249
Planning time: 2.110 ms
Execution time: 17841.944 ms
我對entity_city_state_zip
和agent_city_state_zip
使用各種字體,使用索引嘗試s組合如:
CREATE INDEX ON entities_entity (upper(entity_city_state_zip));
CREATE INDEX ON entities_entity (upper(agent_city_state_zip));
或使用varchar_pattern_ops
,沒有運氣。
服務器使用這樣的事情:
qs = queryset.filter(Q(entity_city_state_zip__icontains = all_city_list) |
Q(agent_city_state_zip__icontains = all_city_list))
生成查詢。
我不知道還有什麼可以嘗試的,
謝謝!
'LIKE'查詢,這與'開始 '%...''將不使用任何B樹索引(包括'xxx_pattern_ops')。只有在模式匹配時纔會選擇這些索引。 (f.ex.' col LIKE'XXX%''或'col〜'^ XXX'')。你可以試試['pg_trgm'模塊](http://www.postgresql.org/docs/current/static/pgtrgm.html),[它爲你提供了一個合適的索引](http://dba.stackexchange。 COM /問題/ 10694 /模式匹配與樣類似到或正則表達式合的PostgreSQL/10696)。 (你可以使用'ilike'來代替like'''lower()'/'upper()'調用)。 – pozs
@pozs我不知道!我會試一試 – NicoSantangelo
我至少想知道'Seq Scan'有什麼影響,以及索引掃描是否可以被替代。看看'set enable_seqscan = false'對計劃有什麼影響。數據庫是否從SSD運行? –