powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ОООочень низкая производительность
12 сообщений из 12, страница 1 из 1
ОООочень низкая производительность
    #33189692
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникает при извлечении данных:
таблица:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
СREATE TABLE period_avg_params
(
  datetime_id int8 NOT NULL,
  param_id int2 NOT NULL,
  event_datetime timestamp NOT NULL,
  value float4 NOT NULL,
  CONSTRAINT period_avg_params_pkey PRIMARY KEY (datetime_id, param_id, event_datetime),
  CONSTRAINT period_avg_params_dt_fkey FOREIGN KEY (datetime_id) REFERENCES period_avg_params_times (datetime_id) ON UPDATE RESTRICT ON DELETE CASCADE,
) 
WITH OIDS;

CREATE INDEX period_avg_params_dt_fkey_index
  ON period_avg_params
  USING btree
  (datetime_id);

CREATE INDEX period_avg_params_param_fkey_index
  ON period_avg_params
  USING btree
  (param_id);

параметров разных (param_id) - около 500... и их необходимо выводить в строчку на каждое одинаковое event_datetime:
Код: plaintext
1.
2.
3.
4.
5.
6.
event_datetime |param_id1|param_id2|...|param_id500|
---------------|---------|---------|---|-----------|
время1         |  10       |  0 . 2      |...|  7 . 2        |
время2         |  23       |  0 . 3      |...|  3 . 2        |
....................................................
времяN         |  23       |  0 . 3      |...|  3 . 2        |
честно говоря - я не очень разобрался сам и мне посоветовали использвать тако й запрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
--такая функуция:
CREATE OR REPLACE FUNCTION coalesce_ag_f(anyelement, anyelement)
  RETURNS anyelement AS
$BODY$
	select coalesce($ 1 ,$ 2 );
$BODY$
  LANGUAGE 'sql' VOLATILE;

--агрегат:
CREATE AGGREGATE coalesce_ag(
  BASETYPE=anyelement,
  SFUNC=coalesce_ag_f,
  STYPE=anyelement,
  FFUNC="-"
);
ALTER AGGREGATE coalesce_ag OWNER TO postgres;

--и собственно сам запрос:
SELECT 
  event_datetime, 
  coalesce_ag("1") as "f",
  coalesce_ag("2") as "U_A",
  coalesce_ag("3") as "U_B",
  coalesce_ag("4") as "U_C",
FROM 
(SELECT DISTINCT event_datetime,
    case param_id when '1' then value else NULL end as "1",
    case param_id when '2' then value else NULL end as "2",
    case param_id when '3' then value else NULL end as "3",
    case param_id when '4' then value else NULL end as "4"
FROM period_avg_params
WHERE datetime_id =  32 ) AS t
GROUP BY event_datetime ORDER BY event_datetime;
при малом количестве параметров - все быстро бегает... а вот если их хотя бы 100 - время запроса растет даже не линейно...
EXPLAIN ANALYZE запроса со 120 параметрами дает вот что:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
"GroupAggregate  (cost=1037.03..1272.06 rows=200 width=476) (actual time=9183.000..53607.000 rows=87 loops=1)"
"  ->  Subquery Scan t  (cost=1037.03..1127.12 rows=293 width=476) (actual time=8663.000..10497.000 rows=10266 loops=1)"
"        ->  Unique  (cost=1037.03..1124.19 rows=293 width=14) (actual time=8603.000..9355.000 rows=10266 loops=1)"
"              ->  Sort  (cost=1037.03..1037.76 rows=293 width=14) (actual time=8603.000..8784.000 rows=46980 loops=1)"
"                    Sort Key: event_datetime, CASE param_id WHEN 2302::smallint THEN value ELSE NULL::real END, CASE param_id WHEN 2303::smallint THEN value ELSE NULL::real END, CASE param_id WHEN 2304::smallint THEN value ELSE NULL::real END, CASE param_i (..)"
"                    ->  Index Scan using period_avg_params_dt_fkey_index on period_avg_params  (cost=0.00..1025.02 rows=293 width=14) (actual time=0.000..5047.000 rows=46980 loops=1)"
"                          Index Cond: (datetime_id = 32)"
"Total runtime: 53627.000 ms"
Господа, ООчень надо разобраться - кто виноват и что делать....
заранее благодарен!
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33189775
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут уже обсуждалось подобное http://www.sql.ru/forum/actualthread.aspx?tid=190031

P.S. "Кто виноват? Да ты сам и виноват. Что делать? Что-то другое" (c)
О.Дивов
извините, не сдержался... :)

Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33189891
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
собственно... это я ветку открывал тогда...
варианты которые рассматривались - все до единого дико тормозят...
просто не пойму - имеет ли смысл копать глубже (понятно - что всегда имеет и я не против - просто время поджимает не кстати)... или нужно перепроектировать базу под внешний вид... вот в чем дилемма)

P.S. касательно P.S.
знаю... к этому все и идет)
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33189926
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аидрей wrote:
> собственно... это я ветку открывал тогда...
> варианты которые рассматривались - все до единого дико тормозят...
Интересно, мой вариант тоже дико тормозит? http://www.sql.ru/forum/actualthread.aspx?tid=190031#1602114
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33190107
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Признаюсь - не уделил пристального внимания предложенному вами варианту...
Просто на тот момент хотелось это сделать... красиво, что ли... (хотя почему именно за красивую сторону принял сторону базы - не могу объяснить... казалось, что так должно быть побыстрее)
Сейчас уже важно - сделать быстрым все это...
поэтому если позволите я немного более детально расспрошу вас о предложенном варианте:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 ArrayList rows=new ArrayList();
 ArrayList cols=new ArrayList();
 // схема a_table ( data int, param varchar, value varchar, unique(data, param) )
 // в rows загоняем результат запроса "select distinct data from a_table order by 1"
 // в cols загоняем результат запроса "select distinct param from a_table order by 1"
 Object[][] data=new Object[rows.Count][cols.Count]; // табличка с данными
 NpgsqlDataAdapter  myCommand = new NpgsqlDataAdapter("select data, param, value from a_table", myConnection);
 DataSet ds=new DataSet();
 myCommand.Fill(ds,"a_table");
 // заполнение таблички данными
 for(DataRow row in ds.Tables["a_table"].Rows)
 {
        int i=rows.IndexOf(row["data"]);
        int j=cols.IndexOf(row["param"]);
        data[i][j]=row["value"];
 }
Насколько я понял - необходимо сначала вытащить все возможные данные вручную... а потом их вставлять в таблицу... (то ли я не понял основной тонкой мысли, то ли это не очень быстро должно выйти, imho)
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33190255
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аидрей
Насколько я понял - необходимо сначала вытащить все возможные данные вручную... а потом их вставлять в таблицу... (то ли я не понял основной тонкой мысли, то ли это не очень быстро должно выйти, imho)
Да, идея в том, чтобы вытянуть все интересующие данные без километровых вложенных SQL подзапросов, группировок и сортировок [ну, почти], а далее растолкать их по соответсвующим ячейкам таблицы.

По поводу скорости - должно работать вполне приемлимо, т.к. используется всего два простых запроса, объем которых не превысит в любом случае результаты вышеприведенных SQL (чаще должны быть существенно меньше).
При "расталкивании" по ячейкам таблицы может тормозить ArrayList.IndexOf, (хотя не знаю наверняка) что можно ускорить, используя хеш-таблицы.

несколько измененный код (если где-то навру с синтаксисом - сильно не пинать!):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
//
// как я понял, cols - набор требуемых param_id'ов уже задан. запрос не нужен
//
ArrayList rows=new ArrayList(); // строки : даты
Hashtable rows_idx=new Hashtable(); // хеш таблица для быстрого поиска номера строки для соотв. даты

NpgsqlDataAdapter  getRows =
        new NpgsqlDataAdapter("select distinct event_datetime from period_avg_params where datetime_id = ? order by 1",
                 myConnection);
NpgsqlDataReader rowReader=myCommand.ExecuteReader();
int num= 0 ; // номер строки
// в rows загоняем результат запроса
while(rowReader.Read()){
        rows.Add(rowReader.GetTimeStamp( 0 ));
        rows_idx.Add(rowReader.GetTimeStamp( 0 ), num++);
}

Object[][] data=new Object[rows.Count][cols.Count]; // табличка с данными - тип на усмотрение :)

NpgsqlDataAdapter  myCommand =
        new NpgsqlDataAdapter("select  param_id, event_datetime, value from period_avg_params where datetime_id = ?",
         myConnection); // тут даже и сортировка не нужна
NpgsqlDataReader reader=myCommand.ExecuteReader();
// заполнение таблички данными, DataSet заменен на DataReader т.к. данные стоит читать только раз
while(reader.Read()){
        int i=(int)rows_idx.Get(reader["event_datetime"]);
        int j=cols.IndexOf(reader["param_id"]);
        data[i][j]=reader["value"];
}
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33190713
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь за вновь прибытие. Согласен, что мой вариант будет тормозить, так
как я немного ошибся :-) Нафиг было запихивать case в подзапрос, сам не
понимаю. Кстати, а DISTINCT там обязателен? В моем варианте его небыло.
Пожалуйста, сообщи результат такого варианта (pleeaase):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
--и собственно сам запрос:
SELECT 
  event_datetime, 
  coalesce_ag(case param_id when '1' then value else NULL end) as "f",
  coalesce_ag(case param_id when '2' then value else NULL end) as "U_A",
  coalesce_ag(case param_id when '3' then value else NULL end) as "U_B",
  coalesce_ag(case param_id when '4' then value else NULL end) as "U_C",
FROM 
  period_avg_params
WHERE datetime_id =  32 
GROUP BY event_datetime ORDER BY event_datetime;
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33190954
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Funny_FalconКстати, а DISTINCT там обязателен? В моем варианте его небыло.
Пожалуйста, сообщи результат такого варианта (pleeaase):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
--и собственно сам запрос:
SELECT 
  event_datetime, 
  coalesce_ag(case param_id when '1' then value else NULL end) as "f",
  coalesce_ag(case param_id when '2' then value else NULL end) as "U_A",
  coalesce_ag(case param_id when '3' then value else NULL end) as "U_B",
  coalesce_ag(case param_id when '4' then value else NULL end) as "U_C",
FROM 
  period_avg_params
WHERE datetime_id =  32 
GROUP BY event_datetime ORDER BY event_datetime;

По поводу DISTINCT - я пытался разобраться - в чем тормоза (а в силу того, что пока делитант) - выполнил отдельно вложенный SELECT - оказалось, что он возвращает кроме всего прочего - кучу записей с NULL - вот я и решил их пообрезать - скорость поднялась примерно раз в 15-20...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
-- результат EXPLAIN ANALYZE SELECT... для 4 записей
"Sort  (cost=943.03..943.04 rows=2 width=14) (actual time=6510.000..6510.000 rows=87 loops=1)"
"  Sort Key: event_datetime"
"  ->  HashAggregate  (cost=942.98..943.02 rows=2 width=14) (actual time=6510.000..6510.000 rows=87 loops=1)"
"        ->  Index Scan using period_avg_params_dt_fkey_index on period_avg_params  (cost=0.00..939.32 rows=293 width=14) (actual time=0.000..590.000 rows=46980 loops=1)"
"              Index Cond: (datetime_id = 32)"
"Total runtime: 6510.000 ms"

-- и то же самое для 10 записей:
"Sort  (cost=947.49..947.49 rows=2 width=14) (actual time=15522.000..15522.000 rows=87 loops=1)"
"  Sort Key: event_datetime"
"  ->  HashAggregate  (cost=947.38..947.48 rows=2 width=14) (actual time=15522.000..15522.000 rows=87 loops=1)"
"        ->  Index Scan using period_avg_params_dt_fkey_index on period_avg_params  (cost=0.00..939.32 rows=293 width=14) (actual time=0.000..430.000 rows=46980 loops=1)"
"              Index Cond: (datetime_id = 32)"
"Total runtime: 15522.000 ms"
Предыдущий вариант работал быстрее...
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33191090
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
XM
По поводу скорости - должно работать вполне приемлимо, т.к. используется всего два простых запроса...
спасибо =) думаю буду попробовать такой вариант =)
кстати хочется спросить (исходя из опыта) - а данные в таблице будут отрисовываться по мере поступления, или по завершению... просто может это как-то в отдельный поток уводить, чтобы не было у пользователя сложностей...
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33191256
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аидрей wrote:
> кстати хочется спросить (исходя из опыта) - а данные в таблице будут
> отрисовываться по мере поступления, или по завершению... просто может
> это как-то в отдельный поток уводить, чтобы не было у пользователя
> сложностей...
Это уже как сами решите, стоит ли уводить в отдельный поток :)
Мой пример - просто создает двумерный массив с соответственно расставленными данными.
Варианты отрисовки (и оценка, тыксказть, юзабилити:) :
1. (не очень приятный, но чуть быстрее)
Повесить сообщение "Получение данных. Ждите...", выгрести все данные и потом скопом отбразить.

2. (чуть приятнее, но чуть медленнее - затраты на UI refresh?)
Повесить ProgressBar : "Получение данных...30%"
(при этом для оценки процентов потребуется еще один запрос типа "select count(*) from period_avg_params WHERE
datetime_id = ? "), выгрести все данные и потом скопом отбразить.

3. (для желающих видеть данные по мере выгребания)
настроить Grid на соотв. размеры и добавлять данные по мере чтения.
В запросе потребуется добавить "order by event_datetime".

4. Комбинация 2 и 3 :)

Лично я бы выбрал вариант 2. (сугубое ИМХО :)
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33191829
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу DISTINCT - я пытался разобраться - в чем тормоза (а в силу того, что пока делитант) - выполнил отдельно вложенный SELECT - оказалось, что он возвращает кроме всего прочего - кучу записей с NULL - вот я и решил их пообрезать - скорость поднялась примерно раз в 15-20...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
"GroupAggregate  (cost=1037.03..1272.06 rows=200 width=476) (actual time=9183.000..53607.000 rows=87 loops=1)"
"  ->  Subquery Scan t  (cost=1037.03..1127.12 rows=293 width=476) (actual time=8663.000..10497.000 rows=10266 loops=1)"
"        ->  Unique  (cost=1037.03..1124.19 rows=293 width=14) (actual time=8603.000..9355.000 rows=10266 loops=1)"
"              ->  Sort  (cost=1037.03..1037.76 rows=293 width=14) (actual time=8603.000..8784.000 rows=46980 loops=1)"
"                    Sort Key: event_datetime, CASE param_id WHEN 2302::smallint THEN value ELSE NULL::real END, CASE param_id WHEN 2303::smallint THEN value ELSE NULL::real END, CASE param_id WHEN 2304::smallint THEN value ELSE NULL::real END, CASE param_i (..)"
"                    ->  Index Scan using period_avg_params_dt_fkey_index on period_avg_params  (cost=0.00..1025.02 rows=293 width=14) (actual time=0.000..5047.000 rows=46980 loops=1)"
"                          Index Cond: (datetime_id = 32)"
"Total runtime: 53627.000 ms"
По идее все данные разные и DISTINCT не должен иметь эффекта. По фильтруй данные с помощью where и будет счастье :-).
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT 
  event_datetime, 
  coalesce_ag(case param_id when '1' then value else NULL end) as "f",
  coalesce_ag(case param_id when '2' then value else NULL end) as "U_A",
  coalesce_ag(case param_id when '3' then value else NULL end) as "U_B",
  coalesce_ag(case param_id when '4' then value else NULL end) as "U_C",
FROM 
  period_avg_params
WHERE datetime_id =  32  and param_id in ('1','2','3','4')
GROUP BY event_datetime ORDER BY event_datetime;
Для малого набора должно помочь, для большого, незнаю.
...
Рейтинг: 0 / 0
ОООочень низкая производительность
    #33191953
Аидрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мда... спасибо за участие... но судя по всему - на моем объеме удобнее делать на стороне клиента...
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ОООочень низкая производительность
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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