Postgresql - 喜欢和按语句排序的表现

时间:2014-04-23 13:54:53

标签: performance postgresql sql-order-by

我的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秒......

0 个答案:

没有答案