我的SQL是:
select *
from "order" as o
inner join "contractor" as client on client.id = o.client_id
inner join "location" as sl on sl.id = o.sender_location_id
inner join "city" as sci on sci.id = sl.city_id
inner join "location" as cl on cl.id = o.consignee_location_id
inner join "city" as cci on cci.id = cl.city_id
inner join "lot" as l on l.id = o.lot_id
inner join "contractor" as ls on l.supplier_id = ls.id
where (sci.name like '%Москва%')
order by sci.name limit 100 offset 10
使用EXPLAIN ANALYZE:
"Limit (cost=901.48..901.48 rows=1 width=4249) (actual time=2608.229..2608.237 rows=100 loops=1)"
" -> Sort (cost=901.41..901.48 rows=27 width=4249) (actual time=2608.224..2608.230 rows=200 loops=1)"
" Sort Key: sci.name"
" Sort Method: top-N heapsort Memory: 215kB"
" -> Nested Loop (cost=664.86..900.77 rows=27 width=4249) (actual time=6.110..2167.654 rows=213534 loops=1)"
" -> Nested Loop (cost=664.58..892.35 rows=27 width=4192) (actual time=6.105..1768.970 rows=213534 loops=1)"
" -> Nested Loop (cost=664.29..843.60 rows=27 width=4149) (actual time=6.099..1370.279 rows=213534 loops=1)"
" -> Nested Loop (cost=664.02..835.35 rows=27 width=3518) (actual time=6.094..986.314 rows=213534 loops=1)"
" -> Nested Loop (cost=663.74..826.97 rows=27 width=3461) (actual time=6.089..615.773 rows=213534 loops=1)"
" -> Nested Loop (cost=663.45..817.38 rows=29 width=3395) (actual time=6.083..156.045 rows=231799 loops=1)"
" -> Hash Join (cost=663.02..696.78 rows=1 width=674) (actual time=6.067..6.395 rows=186 loops=1)"
" Hash Cond: (sl.city_id = sci.id)"
" -> Seq Scan on location sl (cost=0.00..30.00 rows=1000 width=631) (actual time=0.007..0.102 rows=1000 loops=1)"
" -> Hash (cost=662.99..662.99 rows=3 width=43) (actual time=6.047..6.047 rows=1 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 1kB"
" -> Seq Scan on city sci (cost=0.00..662.99 rows=3 width=43) (actual time=3.153..6.046 rows=1 loops=1)"
" Filter: ((name)::text ~~ '%Москва%'::text)"
" Rows Removed by Filter: 29998"
" -> Index Scan using index_order_on_sender_location_id on "order" o (cost=0.42..88.21 rows=3238 width=2721) (actual time=0.002..0.374 rows=1246 loops=186)"
" Index Cond: (sender_location_id = sl.id)"
" -> Index Scan using lot_pkey on lot l (cost=0.29..0.32 rows=1 width=66) (actual time=0.001..0.001 rows=1 loops=231799)"
" Index Cond: (id = o.lot_id)"
" -> Index Scan using contractor_pkey on contractor client (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = o.client_id)"
" -> Index Scan using index_location_on_id on location cl (cost=0.28..0.30 rows=1 width=631) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = o.consignee_location_id)"
" -> Index Scan using city_pkey on city cci (cost=0.29..1.80 rows=1 width=43) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = cl.city_id)"
" -> Index Scan using contractor_pkey on contractor ls (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = l.supplier_id)"
"Total runtime: 2608.618 ms"
如果我删除"按顺序排列":
"Limit (cost=900.77..900.77 rows=1 width=4249) (actual time=6.751..7.818 rows=100 loops=1)"
" -> Nested Loop (cost=664.86..900.77 rows=27 width=4249) (actual time=5.742..7.805 rows=200 loops=1)"
" -> Nested Loop (cost=664.58..892.35 rows=27 width=4192) (actual time=5.738..7.434 rows=200 loops=1)"
" -> Nested Loop (cost=664.29..843.60 rows=27 width=4149) (actual time=5.731..7.062 rows=200 loops=1)"
" -> Nested Loop (cost=664.02..835.35 rows=27 width=3518) (actual time=5.728..6.728 rows=200 loops=1)"
" -> Nested Loop (cost=663.74..826.97 rows=27 width=3461) (actual time=5.723..6.395 rows=200 loops=1)"
" -> Nested Loop (cost=663.45..817.38 rows=29 width=3395) (actual time=5.718..5.942 rows=219 loops=1)"
" -> Hash Join (cost=663.02..696.78 rows=1 width=674) (actual time=5.703..5.729 rows=21 loops=1)"
" Hash Cond: (sl.city_id = sci.id)"
" -> Seq Scan on location sl (cost=0.00..30.00 rows=1000 width=631) (actual time=0.005..0.013 rows=95 loops=1)"
" -> Hash (cost=662.99..662.99 rows=3 width=43) (actual time=5.685..5.685 rows=1 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 1kB"
" -> Seq Scan on city sci (cost=0.00..662.99 rows=3 width=43) (actual time=2.896..5.684 rows=1 loops=1)"
" Filter: ((name)::text ~~ '%Москва%'::text)"
" Rows Removed by Filter: 29998"
" -> Index Scan using index_order_on_sender_location_id on "order" o (cost=0.42..88.21 rows=3238 width=2721) (actual time=0.002..0.007 rows=10 loops=21)"
" Index Cond: (sender_location_id = sl.id)"
" -> Index Scan using lot_pkey on lot l (cost=0.29..0.32 rows=1 width=66) (actual time=0.001..0.002 rows=1 loops=219)"
" Index Cond: (id = o.lot_id)"
" -> Index Scan using contractor_pkey on contractor client (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=200)"
" Index Cond: (id = o.client_id)"
" -> Index Scan using index_location_on_id on location cl (cost=0.28..0.30 rows=1 width=631) (actual time=0.001..0.001 rows=1 loops=200)"
" Index Cond: (id = o.consignee_location_id)"
" -> Index Scan using city_pkey on city cci (cost=0.29..1.80 rows=1 width=43) (actual time=0.001..0.001 rows=1 loops=200)"
" Index Cond: (id = cl.city_id)"
" -> Index Scan using contractor_pkey on contractor ls (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=200)"
" Index Cond: (id = l.supplier_id)"
"Total runtime: 8.058 ms"
我为第I列排序和过滤创建了额外的索引,但似乎它没有在执行时使用:
create index "index_city_on_name" on "city" ("name");
两秒太长了,我可以以某种方式优化查询吗?
编辑:
使用trgm模块后:
"Limit (cost=1068.48..1068.73 rows=100 width=4249) (actual time=2114.401..2114.414 rows=100 loops=1)"
" -> Sort (cost=1068.23..1068.91 rows=274 width=4249) (actual time=2114.390..2114.395 rows=200 loops=1)"
" Sort Key: o.id"
" Sort Method: top-N heapsort Memory: 225kB"
" -> Nested Loop (cost=137.71..1057.13 rows=274 width=4249) (actual time=5.113..1843.159 rows=213534 loops=1)"
" -> Nested Loop (cost=137.43..971.65 rows=274 width=4192) (actual time=5.107..1459.774 rows=213534 loops=1)"
" -> Nested Loop (cost=137.15..476.95 rows=274 width=4149) (actual time=5.101..1062.742 rows=213534 loops=1)"
" -> Hash Join (cost=136.87..391.89 rows=274 width=4092) (actual time=5.095..685.963 rows=213534 loops=1)"
" Hash Cond: (o.consignee_location_id = cl.id)"
" -> Nested Loop (cost=94.37..345.63 rows=274 width=3461) (actual time=4.848..561.232 rows=213534 loops=1)"
" -> Nested Loop (cost=94.08..248.00 rows=295 width=3395) (actual time=4.842..134.151 rows=231799 loops=1)"
" -> Hash Join (cost=93.65..127.41 rows=1 width=674) (actual time=4.827..5.120 rows=186 loops=1)"
" Hash Cond: (sl.city_id = sci.id)"
" -> Seq Scan on location sl (cost=0.00..30.00 rows=1000 width=631) (actual time=0.001..0.103 rows=1000 loops=1)"
" -> Hash (cost=93.28..93.28 rows=30 width=43) (actual time=4.816..4.816 rows=14 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 2kB"
" -> Bitmap Heap Scan on city sci (cost=4.51..93.28 rows=30 width=43) (actual time=4.809..4.811 rows=14 loops=1)"
" Recheck Cond: (name % 'Москва'::text)"
" -> Bitmap Index Scan on index_city_on_name (cost=0.00..4.50 rows=30 width=0) (actual time=4.803..4.803 rows=14 loops=1)"
" Index Cond: (name % 'Москва'::text)"
" -> Index Scan using index_order_on_sender_location_id on "order" o (cost=0.42..88.21 rows=3238 width=2721) (actual time=0.002..0.322 rows=1246 loops=186)"
" Index Cond: (sender_location_id = sl.id)"
" -> Index Scan using lot_pkey on lot l (cost=0.29..0.32 rows=1 width=66) (actual time=0.001..0.001 rows=1 loops=231799)"
" Index Cond: (id = o.lot_id)"
" -> Hash (cost=30.00..30.00 rows=1000 width=631) (actual time=0.238..0.238 rows=1000 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 155kB"
" -> Seq Scan on location cl (cost=0.00..30.00 rows=1000 width=631) (actual time=0.005..0.086 rows=1000 loops=1)"
" -> Index Scan using contractor_pkey on contractor client (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = o.client_id)"
" -> Index Scan using city_pkey on city cci (cost=0.29..1.80 rows=1 width=43) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = cl.city_id)"
" -> Index Scan using contractor_pkey on contractor ls (cost=0.28..0.30 rows=1 width=57) (actual time=0.001..0.001 rows=1 loops=213534)"
" Index Cond: (id = l.supplier_id)"
"Total runtime: 2114.808 ms"
现在指数没有被忽略,但仍然是2秒......