powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выборка максимального вхождения LIKE
13 сообщений из 13, страница 1 из 1
Выборка максимального вхождения LIKE
    #34181468
httt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
EXPLAIN SELECT phone_table.phone,tarif.cod FROM tarif,phone_table WHERE tarif.cod=(SELECT max(tarif.cod) FROM tarif WHERE phone_table.phone LIKE tarif.cod||'%');
                                                       QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
 Merge Join  (cost= 566 . 12 .. 116681 . 48  rows= 7458  width= 22 )
   Merge Cond: ("outer".cod = "inner"."?column2?")
   ->  Index Scan using idx_tarif_cod on tarif  (cost= 0 . 00 .. 143 . 22  rows= 2837  width= 8 )
   ->  Sort  (cost= 566 . 12 .. 583 . 84  rows= 7087  width= 14 )
         Sort Key: (subplan)
         ->  Seq Scan on phone_table  (cost= 0 . 00 .. 112 . 87  rows= 7087  width= 14 )
               SubPlan
                 ->  Result  (cost= 11 . 24 .. 11 . 25  rows= 1  width= 0 )
                       InitPlan
                         ->  Limit  (cost= 0 . 00 .. 11 . 24  rows= 1  width= 8 )
                               ->  Index Scan Backward using idx_tarif_cod on tarif  (cost= 0 . 00 .. 157 . 41  rows= 14  width= 8 )
                                     Filter: ((cod IS NOT NULL) AND ($ 0  ~~ (cod || '%'::text)))
( 12  rows)


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
\d tarif
                         Table "public.tarif"
 Column  |  Type   |                     Modifiers
---------+---------+---------------------------------------------------
 id      | integer | default nextval(('id_tarif_seq'::text)::regclass)
 cod     | text    |
 dop_cod | text    |
 name    | text    |
 zona    | text    |
Indexes:
    "idx_tarif_cod" btree (cod)
    "iiii" btree (cod text_pattern_ops)

\d phone_table
Table "public.phone_table"
 Column | Type | Modifiers
--------+------+-----------
 phone  | text |
Indexes:
    "idx_phone_table_phone" btree (phone)
    "idx_phone_table_phone2" btree (phone text_pattern_ops)
Как заставить работать индекс при использовании LIKE, ищет с начала строки. При следующем запросе индекс ипользуется
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
EXPLAIN SELECT * FROM phone_table WHERE phone LIKE '495%';
                                        QUERY PLAN
-------------------------------------------------------------------------------------------
 Index Scan using idx_phone_table_phone2 on phone_table  (cost= 0 . 00 .. 5 . 97  rows= 1  width= 14 )
   Index Cond: ((phone ~>=~ '495'::text) AND (phone ~<~ '496'::text))
   Filter: (phone ~~ '495%'::text)
( 3  rows)
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34181902
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача поиска префикса максимальной длины в биллинговой системе?
Вот ссылки на обсуждение аналогичных задач:
Тынц №1
Тынц №2
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34182019
glebofff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
billing=# select code, name from route_voip where '73532887788' ~ ('^'||code) order by code desc limit  1 ;
 code  |       name       
-------+------------------
  73532  | Россия, Оренбург
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34182594
httt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
glebofff
Код: plaintext
1.
2.
3.
4.
billing=# select code, name from route_voip where '73532887788' ~ ('^'||code) order by code desc limit  1 ;
 code  |       name       
-------+------------------
  73532  | Россия, Оренбург

Если подставить конкретный номер, то у меня индекс тоже работает, не испольщуется именно при проверки полей (не конкретной строки). Вот пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
EXPLAIN SELECT phone_table.phone,tarif.cod FROM tarif,phone_table WHERE tarif.cod=(SELECT max(tarif.cod) FROM tarif WHERE '749525356' LIKE tarif.cod||'%');
                                                 QUERY PLAN
-------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost= 11 . 25 .. 200 . 65  rows= 7087  width= 22 )
   InitPlan
     ->  Result  (cost= 11 . 24 .. 11 . 25  rows= 1  width= 0 )
           InitPlan
             ->  Limit  (cost= 0 . 00 .. 11 . 24  rows= 1  width= 8 )
                   ->  Index Scan Backward using idx_tarif_cod on tarif  (cost= 0 . 00 .. 157 . 41  rows= 14  width= 8 )
                         Filter: ((cod IS NOT NULL) AND ('749525356'::text ~~ (cod || '%'::text)))
   ->  Index Scan using idx_tarif_cod on tarif  (cost= 0 . 00 .. 5 . 65  rows= 1  width= 8 )
         Index Cond: (cod = $ 1 )
   ->  Seq Scan on phone_table  (cost= 0 . 00 .. 112 . 87  rows= 7087  width= 14 )
( 10  rows)
Из примера поссылке не работает функция position, сейчас разбираюсь почему.
PS: Postgres 8.1.4
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34182767
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю, лучший ли вариант, но я использую индекс по ( (code || 'z'), code)
и ищу с условием called <=code ||'z' and called >= code
Скорость устраивает.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183026
httt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Funny_FalconНе знаю, лучший ли вариант, но я использую индекс по ( (code || 'z'), code)
и ищу с условием called <=code ||'z' and called >= code
Скорость устраивает.
Как часто происходит расчет? Раз в месяц или поле прохождения звонка каким-нибудь триггером?
У меня тот запрос при 7000 звонков выполняется 15-25 сек на машине 512 Mb, Cel2.2. В принципе приемлимо, но хотелось бы лучше. Предполагается расчитывать раз в месяц и выставлять счета, возможно по отдельным клиентам показывать это через клиентский web-интерфейс.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183778
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запрос выполняется очень часто. У меня задержки биллингования составляют 10 сек (просто чтобы не грузить сервак)

Скажу, что 400 звонков я биллингую за полторы секунды, при этом таких запросов 3-4 штуки.

Сейчас попробую только такой запрос зделать на выборке из таблицы.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183799
httt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Funny_FalconЗапрос выполняется очень часто. У меня задержки биллингования составляют 10 сек (просто чтобы не грузить сервак)

Скажу, что 400 звонков я биллингую за полторы секунды, при этом таких запросов 3-4 штуки.

Сейчас попробую только такой запрос зделать на выборке из таблицы.
Можете скинуть поподробнее запросы и структуры табличек?.. а то так не совсем все понятно.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183811
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
38158 звонков
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
-- Executing query:
select distinct on (vt.id, vt.called) vt.id, codes.zone
from voicet_back.voicet_finished vt
join codes
on codes.code || 'z' > vt.called and codes.code <= vt.called
where time_start > '2006-12-07'
and zone_code_group_id IS NOT NULL -- не обращайте внимания, индекс так определён
order by vt.id, vt.called, codes.code desc

Total query runtime:  22097  ms.
 38158  rows retrieved.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183833
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE TABLE codes
(
  code character varying( 50 ) NOT NULL,
  "zone" character varying( 50 ) NOT NULL,
  description character varying( 50 ) NOT NULL,
  id serial NOT NULL,
  zone_code_group_id integer,
  time_from timestamp with time zone DEFAULT now(),
  time_to timestamp with time zone DEFAULT '2038-01-01 00:00:00+03'::timestamp with time zone,
  CONSTRAINT codes_pkey PRIMARY KEY (id),
  CONSTRAINT codes_zone_code_group_id_fkey FOREIGN KEY (zone_code_group_id)
      REFERENCES zone_code_groups (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
) 
WITHOUT OIDS;
ALTER TABLE codes OWNER TO postgres;

CREATE INDEX codes_ix_code
  ON codes
  USING btree
  ((code::text || 'z'::text), code)
  --- WHERE zone_code_group_id IS NOT NULL; -- не обращайте внимания
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34183887
postt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для чего используется || 'z'?
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34184074
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
'8'    <= '84955555555' < '8z'
'84'   <= '84955555555' < '84z'
'849'  <= '84955555555' < '849z'
'8495' <= '84955555555' < '8495z'

'8495' <= '84966666666' > ' 8495z'
'8495' >  '84944444444' < '8495z'

code || z использется для того, чтобы индекс эффективнее работал.
...
Рейтинг: 0 / 0
Выборка максимального вхождения LIKE
    #34184083
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очепятка

Код: plaintext
1.
2.
3.
4.
5.
'8'    <= '84955555555' < '8z'
'84'   <= '84955555555' < '84z'
'849'  <= '84955555555' < '849z'
'8495' <= '84955555555' < '8495z'
'8495' <= '84966666666' > '8495z'
'8495' >  '84944444444' < '8495z'
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выборка максимального вхождения LIKE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]