Оптимизировать сортировку

whirlwind

TDD infected, paranoid
Оптимизировать сортировку

Есть запрос

[sql]
SELECT tab_file.id, tab_file.name, tab_file.path, tab_file.timepos, tab_file.size, tab_file.host, tab_host.id, tab_host.name, tab_host.port, tab_host.proto, tab_host.ip FROM tab_file,tab_host WHERE (((tab_file.timepos>='2007-05-02 00:00:00')) AND NOT EXISTS(SELECT ref FROM tab_lexindex AS subq WHERE subq.lex IN ('topplan2', 'для') AND subq.ref=tab_file.id) AND tab_host.id=tab_file.host) ORDER BY tab_file.path,tab_file.name LIMIT 20;
[/sql]

такого плана

Код:
 Limit  (cost=732.25..732.30 rows=20 width=142) (actual time=453.000..453.000 rows=20 loops=1)
   ->  Sort  (cost=732.25..732.31 rows=25 width=142) (actual time=453.000..453.000 rows=20 loops=1)
         Sort Key: tab_file.path, tab_file.name
         ->  Nested Loop  (cost=0.00..731.67 rows=25 width=142) (actual time=0.000..390.000 rows=219 8 loops=1)
               Join Filter: ("outer".id = "inner".host)
               ->  Seq Scan on tab_host  (cost=0.00..1.01 rows=1 width=29) (actual time=0.000..0.000  rows=1 loops=1)
               ->  Index Scan using tab_file_timeposidx on tab_file  (cost=0.00..730.34 rows=25 width=113) (actual time=0.000..375.000 rows=2198 loops=1)
                     Index Cond: (timepos >= '2007-05-02 00:00:00'::timestamp without time zone)
                     Filter: (NOT (subplan))
                     SubPlan
                       ->  Index Scan using tab_lexindex_refidx on tab_lexindex subq  (cost=0.00..12.06 rows=1 width=4) (actual time=0.037..0.037 rows=1 loops=8949)
                             Index Cond: (ref = $0)
                             Filter: (((lex)::text = 'topplan2'::text) OR ((lex)::text = 'для'::text))
 Total runtime: 453.000 ms
(14 rows)
Можно ли как-то ускорить сортировку?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: whirlwind
Можно ли как-то ускорить сортировку?
Сортировку нельзя "ускорить", без неё можно обойтись, если идёт выборка по индексу, содержащему поля, по которым сортируем. Но в текущем случае индекс для выборки из tab_file уже и так используется.
 

whirlwind

TDD infected, paranoid
Вообще типовые запросы покрупнее. У мя просто все идеи кончились по оптимизации

[sql]
SELECT [skipped]
FROM tab_lexindex LEFT JOIN tab_lexindex AS t1 ON (t1.ref=tab_lexindex.ref),tab_file,tab_host WHERE (((
tab_file.timepos>='2007-05-02 00:00:00')) AND t1.lex='mults' AND tab_lexindex.lex='avi' AND
tab_lexindex.ref=tab_file.id AND NOT EXISTS(SELECT ref FROM tab_lexindex AS subq WHERE subq.lex IN
('topplan2', 'для') AND subq.ref=tab_file.id) AND tab_host.id=tab_file.host) ORDER BY tab_file.path,
tab_file.name LIMIT 20;
[/sql]

Код:
 Limit  (cost=25954.72..25954.73 rows=1 width=140) (actual time=250.000..250.000 rows=20 loops=1)
   ->  Sort  (cost=25954.72..25954.73 rows=1 width=140) (actual time=250.000..250.000 rows=20 loops=1)
         Sort Key: tab_file.path, tab_file.name
         ->  Nested Loop  (cost=21024.25..25954.71 rows=1 width=140) (actual time=250.000..250.000 rows=22 loops=1)
               Join Filter: ("inner".id = "outer".host)
               ->  Nested Loop  (cost=21024.25..25953.69 rows=1 width=111) (actual time=250.000..250.000 rows=22 loops=1)
                     ->  Merge Join  (cost=21024.25..21053.22 rows=260 width=8) (actual time=172.000..204.000 rows=2149 loops=1)
                           Merge Cond: ("outer".ref = "inner".ref)
                           ->  Sort  (cost=10512.13..10518.72 rows=2637 width=4) (actual time=125.000..125.000 rows=18102 loops=1)
                                 Sort Key: tab_lexindex.ref
                                 ->  Index Scan using tab_lexindex_lexidx on tab_lexindex  (cost=0.00..10362.28 rows=2637 width=4) (actual time=0.000..47.000 rows=18143 loops=1)
                                       Index Cond: ((lex)::text = 'avi'::text)
                           ->  Sort  (cost=10512.13..10518.72 rows=2637 width=4) (actual time=31.000..47.000 rows=2756 loops=1)
                                 Sort Key: t1.ref
                                 ->  Index Scan using tab_lexindex_lexidx on tab_lexindex t1  (cost=0.00..10362.28 rows=2637 width=4) (actual time=0.000..31.000 rows=2756 loops=1)
                                       Index Cond: ((lex)::text = 'mults'::text)
                     ->  Index Scan using tab_file_pkey on tab_file  (cost=0.00..18.84 rows=1 width=111) (actual time=0.000..0.000 rows=0 loops=2149)
                           Index Cond: (tab_file.id = "outer".ref)
                           Filter: ((timepos >= '2007-05-02 00:00:00'::timestamp without time zone) AND (NOT (subplan)))
                           SubPlan
                             ->  Index Scan using tab_lexindex_refidx on tab_lexindex subq  (cost=0.00..13.30 rows=1 width=4) (actual time=0.000..0.000 rows=0 loops=22)
                                   Index Cond: (ref = $0)
                                   Filter: (((lex)::text = 'topplan2'::text) OR ((lex)::text = 'для'::text))
               ->  Seq Scan on tab_host  (cost=0.00..1.01 rows=1 width=29) (actual time=0.000..0.000 rows=1 loops=22)
 Total runtime: 250.000 ms
Может что то еще можно выжать? Структуру готов менять, если поможет.

-~{}~ 04.05.07 11:24:

Блин, хрень какая-то. Убираю сортировку - быстро. Добавляю - тормозит. При чем эксплайн показывает вполне приемлимые цифры и тормоза не на мс, а пропорционально колву условий (например было 0.4s стало минута).

Гдето в мануале видел кластеры или что то в этом роде не могу найти где. Вроде они для сортировки используются? Камрады, пните в нужном направлении плз.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Ну тут у тебя, судя по всему, полнотекстовый поиск делается... Думаю стоит в первую очередь попробовать полнотекстовый индекс построить.
 
Сверху