powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Странное поведение при использовании вложенного запроса
12 сообщений из 12, страница 1 из 1
Странное поведение при использовании вложенного запроса
    #39421209
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Подскажите в чем может быть ошибка?
Не знаю с чего начать, поэтому начну от проблемы.

Такой запрос выполняется нормально, быстро примерно 125ms
Код: plsql
1.
2.
3.
SELECT dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd 
FROM traffic WHERE datetime >= (SELECT now()::date) and src like '192.168.33.1' and dport=53 
GROUP BY dst ORDER BY rcvd DESC;



Следующий запрос не выполняется, точнее заканчивается неудачно по таймауту:
Код: plsql
1.
2.
3.
SELECT dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd 
FROM traffic WHERE datetime >= (SELECT now()::date) and src like '192.168.33.1' and dport=1025 
GROUP BY dst ORDER BY rcvd DESC;


Отличается только выбираемым значением dport=1025

Следующий запрос выполняется быстро:
Код: plsql
1.
2.
3.
SELECT dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd 
FROM traffic WHERE datetime >= '2017-03-17' and src like '192.168.33.1' and dport=1025 
GROUP BY dst ORDER BY rcvd DESC;


Отличается от предыдущего отсутствием вложенного запроса (datetime >= '2017-03-17')

СУБД postgres (PostgreSQL) 9.4.10
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
traflogdb=> \d traffic
                                     Таблица "public.traffic"
 Колонка  |             Тип             |                       Модификаторы
----------+-----------------------------+----------------------------------------------------------
 lineid   | bigint                      | NOT NULL DEFAULT nextval('traffic_lineid_seq'::regclass)
 datetime | timestamp without time zone | NOT NULL
 namedev  | character varying(10)       | NOT NULL
 src      | character varying(16)       | NOT NULL
 sport    | integer                     |
 dst      | character varying(16)       | NOT NULL
 dport    | integer                     |
 message  | character varying(20)       |
 duration | integer                     | NOT NULL
 sent     | integer                     |
 rcvd     | integer                     |
 protoid  | smallint                    | NOT NULL
 proto    | character varying(16)       |
 mac      | character varying(18)       |
Индексы:
    "traffic_pkey" PRIMARY KEY, btree (lineid)
    "traffic_index_datetime" btree (datetime)
    "traffic_index_dport" btree (dport)
    "traffic_index_dst" btree (dst)
    "traffic_index_src" btree (src)


Код: plsql
1.
2.
3.
4.
5.
traflogdb=> select pg_table_size('traffic');
 pg_table_size
---------------
    8274214912
(1 строка)
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421216
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
itoeng,

планы выполнеия каждого из запросов что показывают?
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421267
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так что ли?

1 запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
traflogdb=> EXPLAIN SELECT dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd FROM traffic WHERE datetime >= (SELECT now()::date) and src like '192.168.33.1' and dport=53 GROUP BY dst ORDER BY rcvd DESC;
                                                 QUERY PLAN
-------------------------------------------------------------------------------------------------------------
 Sort  (cost=986404.28..986404.30 rows=5 width=20)
   Sort Key: (sum(rcvd))
   InitPlan 1 (returns $0)
     ->  Result  (cost=0.00..0.01 rows=1 width=0)
   ->  HashAggregate  (cost=986404.16..986404.21 rows=5 width=20)
         Group Key: dst
         ->  Index Scan using traffic_index_datetime on traffic  (cost=0.56..985517.22 rows=118258 width=20)
               Index Cond: (datetime >= $0)
               Filter: (((src)::text ~~ '192.168.33.1'::text) AND (dport = 53))
(9 строк)



2 запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
traflogdb=> EXPLAIN SELECT dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd FROM traffic WHERE datetime >= (SELECT now()::date) and src like '192.168.33.1' and dport=1025 GROUP BY dst ORDER BY rcvd DESC;
                                                  QUERY PLAN
--------------------------------------------------------------------------------------------------------------
 Sort  (cost=189281.92..189281.92 rows=1 width=20)
   Sort Key: (sum(rcvd))
   InitPlan 1 (returns $0)
     ->  Result  (cost=0.00..0.01 rows=1 width=0)
   ->  HashAggregate  (cost=189281.88..189281.89 rows=1 width=20)
         Group Key: dst
         ->  Bitmap Heap Scan on traffic  (cost=63864.90..189189.38 rows=12334 width=20)
               Recheck Cond: (dport = 1025)
               Filter: ((datetime >= $0) AND ((src)::text ~~ '192.168.33.1'::text))
               ->  BitmapAnd  (cost=63864.90..63864.90 rows=37003 width=0)
                     ->  Bitmap Index Scan on traffic_index_src  (cost=0.00..27561.36 rows=1146773 width=0)
                           Index Cond: ((src)::text = '192.168.33.1'::text)
                     ->  Bitmap Index Scan on traffic_index_dport  (cost=0.00..36297.12 rows=1865674 width=0)
                           Index Cond: (dport = 1025)
(14 строк)



3 запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
traflogdb-> GROUP BY dst ORDER BY rcvd DESC;
                                              QUERY PLAN
-------------------------------------------------------------------------------------------------------
 Sort  (cost=1772.79..1772.79 rows=1 width=20)
   Sort Key: (sum(rcvd))
   ->  HashAggregate  (cost=1772.77..1772.78 rows=1 width=20)
         Group Key: dst
         ->  Index Scan using traffic_index_datetime on traffic  (cost=0.56..1772.60 rows=22 width=20)
               Index Cond: (datetime >= '2017-03-17 00:00:00'::timestamp without time zone)
               Filter: (((src)::text ~~ '192.168.33.1'::text) AND (dport = 1025))
(7 строк)
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421272
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извиняюсь за форматирование поста выше.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421283
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
itoeng,

попробуйте переписать в виде datetime >= now()::date, т.е. без подзапроса.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421291
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexius,

Гениально.

Спасибо большое, это решило проблему.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421318
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
itoeng,

есть ещё и такой литерал даты:
Код: sql
1.
select date'today'


он в планах ведёт себя лучше now()::date.
-- фича, думаю, в том , что литералы "исчисляются " до планирования. как и иммутабные значения. правда ли оно, и чем чревато при смене суток (т.е. в какой момент определяется current_timestamp транзакции -- на начало планирования или на начало исполнения) -- надо думать/тестировать.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421338
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Спасибо, буду знать.

Вообще по началу использовал date_trunc ('day' , now()), но когда освоил EXPLAIN заметил что стоимость запроса с ним выше.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421389
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а чего у вас адреса varchar'овые, а не inet ?

Для показанных запросов напрашивается индекс dport & src & datetime или src & dport & datetime. Надо смотреть другие запросы, какой порядок смогут использовать и другие запросы тоже.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421460
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,

Не знал что так можно, приму к сведению. Первый раз делаю проект такого уровня. Набиваю шишки.
С индексами возился месяц назад, сначала делал связанные несколькими полями, но работало плохо, возможно как раз проблема была во вложенном запросе. Но добился стабильной работы сделав несвязанные несколькими полями.

Расскажите, если не трудно, в чем преимущество предложенного вами индекса?

Пока у меня есть три запроса генерируемых из POST запросов из веб страницы CGI.

Код: plsql
1.
2.
3.
4.
SELECT src, SUM (sent) AS sent, SUM (rcvd) AS rcvd 
FROM traffic
WHERE datetime >= now()::date and src like '192.168.%' 
GROUP BY src ORDER BY rcvd DESC



Код: plsql
1.
2.
3.
4.
5.
SELECT
dport, SUM (sent) AS sent, SUM (rcvd) AS rcvd
FROM traffic
WHERE datetime >= now()::date and src like '$form{src}'
GROUP BY dport ORDER BY rcvd DESC



Код: plsql
1.
2.
3.
4.
5.
SELECT
dst, SUM (sent) AS sent, SUM (rcvd) AS rcvd
FROM traffic
WHERE datetime >= now()::date and src like '$form{src}' and dport='$form{dport}'
GROUP BY dst ORDER BY rcvd DESC
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39421489
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема была, вероятно, в порядке полей в индексе. Для btree он критично важен.
Сейчас ваш запрос вычитывает хвост индекса по дате, затем лезет в таблицу за соответствующими строками, чтобы выбросить все строки, не подходящие под остальные условия.
Второй explain как раз показывает, что планировщик решил не идти по индексу по дате, вместо этого bitmap'ом пройтись по индексам по src и номеру порта.
А составной индекс позволяет быстренько по индексу пройти и прочитать строки уже подходящие под условия src и dport. Шикарно описано вот тут: http://use-the-index-luke.com/

С такими 3 запросами можно оставить составной индекс по src, datetime. Затем уже при необходимости по src, dport, datetime. Сейчас похоже данных не много и индекс src & datetime будет достаточно селективен и сам по себе.
...
Рейтинг: 0 / 0
Странное поведение при использовании вложенного запроса
    #39423620
itoeng
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij , спасибо за разъяснения.
Попробовал сделать составной индекс src, datetime с таким индексом запросы выполняются заметно быстрее.

Еще несколько вопросов:
1 Подскажите как, будет происходить такое преобразование данных на живой БД ? Можно ли вообще это делать на живой? или лучше на время приостановить insert`ы?
Код: plsql
1.
2.
3.
ALTER TABLE traffic_test ALTER COLUMN src TYPE inet USING src::inet ;
ALTER TABLE traffic_test ALTER COLUMN dst TYPE inet USING dst::inet ;
ALTER TABLE traffic_test ALTER COLUMN mac TYPE macaddr USING mac::macaddr ;



2 Я так понимаю после преобразования, для фактического изменения размера БД, надо будет выполнять ANALYZE, VACUUM. Так ли это?

3 Надо ли после преобразования выполнять перестройку индексов или они будут перестраиваться автоматически во время выполнения преобразования?
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Странное поведение при использовании вложенного запроса
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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