Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.12.02;
Скачать: [xml.tar.bz2];

Вниз

Замедление DataSet.next   Найти похожие ветки 

 
wsv ©   (2007-07-13 10:28) [0]

Здравствуйте.
Столкнулся с проблемой при больших DataSet-ах с доступом к MySql с помщью компонентов Zeos.
В DataSet (точнее ZQuery, который наследник DataSet), выбирается большое количество данных, 50 тысяч строк и более.
При считывании результата запроса циклом while...do begin ... Dataset.next... происходит замеделение считывания, которое визуально отловлено простым прогрессором.

КАК ИЗБАВИТЬСЯ?

Может можно как-то другими способами скопировать результат в массив?

В частном случае копируются данные типа duoble в масив соотв. типа... В общем случае это вариантные данные.


 
Ega23 ©   (2007-07-13 10:34) [1]

зачем тебе 50 000 записей на клиенте?????


 
Johnmen ©   (2007-07-13 10:34) [2]


> выбирается большое количество данных, 50 тысяч строк и более.

Зачем иметь сразу столько данных на клиенте?


 
sniknik ©   (2007-07-13 10:49) [3]

> while...do begin ... Dataset.next... происходит замеделение считывания, которое визуально отловлено простым прогрессором.
имхо, все дело в волшебных пузырьках... т.е. точках, next не причем.
хотя, не зная особенностей Zeos, могу и ошибаться.

> КАК ИЗБАВИТЬСЯ?
исправить ошибку. сначала, а после задуматься "а нафига тебе столько данных на клиенте?" (если не исправить то притормаживание просто "смажется" малым количеством... останется но не будет так заметно)


 
Desdechado ©   (2007-07-13 10:59) [4]

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


 
wsv ©   (2007-07-13 11:01) [5]


> Зачем иметь сразу столько данных на клиенте?


> зачем тебе 50 000 записей на клиенте?????


Это навигационные данные, которые поступают каждые 15-30 секунд.
Нужен отчет за период.
Границы периода неизвестны. Данные нужно обработать сначала.


 
Desdechado ©   (2007-07-13 11:03) [6]

> Нужен отчет за период. Границы периода неизвестны.
"Принеси то, не знаю что?"

> Это навигационные данные, которые поступают каждые 15-30 секунд.
А причем тут отчет?


 
Сергей М. ©   (2007-07-13 11:04) [7]


> Данные нужно обработать сначала


Почему бы не обработать их на стороне сервера ?


 
wsv ©   (2007-07-13 11:07) [8]


> "Принеси то, не знаю что?"

Период конечно известен. Это наше время. В общем случае - год-два-три...

> А причем тут отчет?

Отчет при том, что нужно сначала отловить обработкой заправки-сливы-остановки-стоянки, что уже сделано. На данных до 30 тыс. строк обработка (считывание+собственно поиск) занимает меньше секунды. Дальше, только передача данных из запроса в массив занимает уже десятки секунд. Например на 100 тыс записей - это 18 секунд передачи в массив.

Как выйти из положения?


 
wsv ©   (2007-07-13 11:08) [9]


> Почему бы не обработать их на стороне сервера ?


Ога... Вейвлет преобразование и фильтрация силами Мускула? :-D


 
sniknik ©   (2007-07-13 11:11) [10]

> Как выйти из положения?
общеизвестный выход из положения - родить. ;о)
в твоем случае разродиться исходной информацией... (сам, я так понимаю, ошибку найти не в состоянии)


 
Сергей М. ©   (2007-07-13 11:12) [11]


> Вейвлет преобразование и фильтрация силами Мускула?


Почему бы и нет ?

Я не в курсе, но разве Мускул не предоставляет механизма использования внешних пользовательских функций, подобного механизму UDF в IB ?

А если и не предоставляет, то все равно непонятно, нафига каждый раз тащить  все даннные, а не только вновь поступившие..


 
Плохиш ©   (2007-07-13 11:16) [12]


> Дальше, только передача данных из запроса в массив занимает
> уже десятки секунд. Например на 100 тыс записей - это 18
> секунд передачи в массив.

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


 
wsv ©   (2007-07-13 11:17) [13]

Исходная информация. D7-Zeos-MySql.
Навиг. данные: очень частая пилА - топливный датчик, показания с которого нифига не интегрированы.
1. Получаем данные датчика за период.
2. Загоняем в массив.
3. Преобразуем вейвлетом.
4. Линеаризуем.
5. Приводим к тарировке датчика
6. Ищем сливы-заправки
7. Выводим график расхода по тарировке и вероятные сливы-заправки.

Проблема в п.2
Все остальное очень быстро робит.


 
wsv ©   (2007-07-13 11:18) [14]


> нафига каждый раз тащить  все даннные, а не только вновь
> поступившие..

не все. за период, указанный юзером.


 
sniknik ©   (2007-07-13 11:21) [15]

> Исходная информация. D7-Zeos-MySql.
это не то ... интересуют "волшебные пузырьки" в коде их [0], а именно как делаешь то что по твоему тормозит.


 
wsv ©   (2007-07-13 11:24) [16]


> а именно как делаешь то что по твоему тормозит.


i:=0;
dm.navdata.First;
while i<RowCount do
begin
fuelout[i]:=dm.navdata.fieldbyname("....").Value;
dm.navdata.Next;
inc(i);
pb.StepBy(1);
end;


 
wsv ©   (2007-07-13 11:25) [17]

А можно как-то по другому?
Вот и спрашиваю, чо... :-D


 
sniknik ©   (2007-07-13 11:26) [18]

меня например очень интересует используешь ли ты отключение контролов, как идет доступ к полям, и не используешь ли ты чего нибудь что вычисляется на основе рекордсета (либо может вычисляться, смотря от того как сделаны Zeos-ы, (тут, от незнания, могу только предполагать, что это))


 
wsv ©   (2007-07-13 11:27) [19]

Контролов связанных с датасетами нет вообще.
Все в массивах.


 
Сергей М. ©   (2007-07-13 11:27) [20]


> не все. за период, указанный юзером


Откуда тогда взялось значение RowCount ?


 
wsv ©   (2007-07-13 11:30) [21]


> Откуда тогда взялось значение RowCount ?

Блин... :-D
dm.navdata.close;
dm.navdata.sql.text:="Select ... from ... where...";
dm.navdata.open;

rowcount:=dm.navdata.rowcount;

:-D


 
sniknik ©   (2007-07-13 11:30) [22]

ага,  ну вот [16], более менее
отключения контролов нет, RowCount поменяй на not eof, fieldbyname вынеси за пределы цикла, и StepBy делай не на каждую итерацию, а на видимую часть (видиш к примеру 100 квадратиков в прогрессе, рассчитай так чтобы было 100 StepBy)
изменилось чтонибудь?


 
wsv ©   (2007-07-13 11:35) [23]


> fieldbyname вынеси за пределы цикла

Это как? :-)
можно сделать fieldvalues или fields.field[0]... но как "вынести за цикл"?


> RowCount поменяй на not eof

Делал. Тоже самое.


 
Сергей М. ©   (2007-07-13 11:37) [24]


> rowcount:=dm.navdata.rowcount


Я не в курсе, что там творится в потрохах Zeos, но глубоко сомневаюсь, что RowCount вернет истинное число записей в выборке.


 
wsv ©   (2007-07-13 11:38) [25]


> отключения контролов нет,


> Контролов связанных с датасетами нет вообще.


Есть еще вариант разбить заданный период и/или выкинуть точки, неудовл. определенным условиям. например, нули, т.е. где сигнала не было. но после этого нужно будет запоминать откуда их выкинули и добавлять обратно в массив.


 
Плохиш ©   (2007-07-13 11:39) [26]


> wsv ©   (13.07.07 11:35) [23]
>
> > fieldbyname вынеси за пределы цикла
>
> Это как? :-)
> можно сделать fieldvalues или fields.field[0]... но как
> "вынести за цикл"?

var
     tmpField: T<xxx>Field;
...
 tmpField := dm.navdata.fieldbyname("....");
 while not dm.navdata.eof do
....


 
wsv ©   (2007-07-13 11:39) [27]


> RowCount вернет истинное число записей в выборке.


Возвращает правильно. Сомневаться не приходится, ибо инвалид поинтер оперэйшен... :-)


 
Desdechado ©   (2007-07-13 11:40) [28]

>  но как "вынести за цикл"?
FieldByName возвращает указатель на поле. Сохрани его до цикла. Это сильно влияет на скорость. Потом просто в цикле будет указатель.As...

Кроме того мне не понятно, зачем еще раз данные читать в массив, если они уже есть в датасете (тот же массив).


 
Плохиш ©   (2007-07-13 11:41) [29]

и окружить всё в

dm.navdata.DisableControls;
try
  // Твой код
finally
 dm.navdata.EnableControls;
end;


PS. Тормознутые эти zeos, я бы перешёл на адо :-)


 
sniknik ©   (2007-07-13 11:42) [30]

> Это как? :-)
> можно сделать fieldvalues или fields.field[0]... но как "вынести за цикл"?
var
 Fld: TField;
begin
 Fld:= dm.navdata.fieldbyname("....");
 while i<RowCount do
   Fld.Value;

у многих получение индекса поля по имени расчетное... т.е. тратит время.
> RowCount поменяй на not eof
> Делал. Тоже самое.
это просто более правильно, но когда писал не было этого
> rowcount:=dm.navdata.rowcount;
тут тебе можно просто for i:= 0 to ... поставить, этот цикл быстрее изза другого рода проверки выхода (а она каждый раз не нужна т.к. судя по всему рекордсет локальный)

а StepBy? возьми просто убери прогресс и засеки общее время, и контнролы отключи обязательно даже если их нет (проверка может быть на разных уровнях вложенности, отключенные тобой это самый первый уровень, быстрее всего)


 
wsv ©   (2007-07-13 11:43) [31]


> Кроме того мне не понятно, зачем еще раз данные читать в
> массив, если они уже есть в датасете (тот же массив).


Представь если еще бегать при линеаризации, тарировке и поиске заправок и сливов по датасету... :-D
Именно поэтому и массивы.


 
sniknik ©   (2007-07-13 11:44) [32]

> PS. Тормознутые эти zeos, я бы перешёл на адо :-)
точно знаеш? работал?


 
Сергей М. ©   (2007-07-13 11:45) [33]


> Возвращает правильно


С чего ты так уверен ?

Last после открытия НД ты явно не делаешь, делает ли это неявно Zeos ты тоже не знаешь, предоставляет ли эту "фичу" сам Мускул - тебе тоже неведомо..


> Сомневаться не приходится, ибо инвалид поинтер оперэйшен


Чевой-то ?)


 
sniknik ©   (2007-07-13 11:46) [34]

> Представь если еще бегать при линеаризации, тарировке и поиске заправок и сливов по датасету... :-D
а если не бегать? если составить запрос на обьеденение так чтобы все рядом было?


 
wsv ©   (2007-07-13 11:47) [35]


> С чего ты так уверен ?


Потому што при заполнении массива нет ошибок.


 
Плохиш ©   (2007-07-13 11:47) [36]


> sniknik ©   (13.07.07 11:44) [32]
> > PS. Тормознутые эти zeos, я бы перешёл на адо :-)
> точно знаеш? работал?

Хотел перейти, начитавшись рекламы :-) Переделал проект с адо на зеос и время обработки увеличилось в 4 раза, покрутил ещё там чего-то немного и забросил. Теперь пользуюсь стандартными проверенными технологиями :-)


 
wsv ©   (2007-07-13 11:50) [37]


> а если не бегать? если составить запрос на обьеденение так
> чтобы все рядом было?


Данные тарировки физически лежат в другой базе. На этапе разработки они просто загнаны в мемо (их около 10 строк всего). Они тоже читаются в массивчик и входные данные тарируются клиентом.

А с чем объединить еще, я не знаю. :-D


 
sniknik ©   (2007-07-13 11:51) [38]

> Потому што при заполнении массива нет ошибок.
а с чего им быть если rowcount вернул частичное значение количества на еще не полностью скачанном рекордсете, массив ты сформировал по этому размеру и перенос сделал по нему же, не обращая внимания что данных уже больше.
(я вообщето подумал что у тебя клиентский курсор, наподобие в ADO, и данные приходят все без докачек...)


 
Сергей М. ©   (2007-07-13 11:52) [39]


> Потому што при заполнении массива нет ошибок


А с какого перепугу они должны возникнуть ?

Открыв НД ты тут же прочитал св-во RowCount, пребывая в святой уверенности в том что получил действительное число записей в этом НД, после чего выделил соответствующую память под массив. Где здесь "криминал" ? Нету его) ... Засада же может поджидать тебя с совершенно иной сторона - число записей в НД в реальности больше, чем то что ты получил вот таким макаром.


 
Anatoly Podgoretsky ©   (2007-07-13 11:55) [40]

Это типичный однонаправленный набор данных!
И определение массива не приведено.


 
wsv ©   (2007-07-13 11:59) [41]

По количеству записей вопросов нет. :-D

Есть вопрос по скорости чтения результатов запроса... Ну или копированию этих результатов в массив...

ЗЫ. Данные выбираются ВСЕ. Это точно. Про баги с RowCount я знаю и проверял на начальном этапе....
ЗЗЫ. tfield выключил. DisableControls добавил. Немного ускорилось. Добавил к периоду неделю с приемлемой скоростью. За это СПАСИБО.


 
Сергей М. ©   (2007-07-13 12:00) [42]


> Это типичный однонаправленный набор данных


Это он использует его как однонаправленный.

А сам НД вполне может у него быть и двунаправленным, о чем он вероятно не подозревает и не задумывается.

Оттого и "тормоза" ощутимые (если не сказать основные) добавляются, плюс ко всем тем очевидным "кривостям" и неоптимальностям в коде, что он привел)


 
wsv ©   (2007-07-13 12:00) [43]


> Это типичный однонаправленный набор данных!
> И определение массива не приведено.


fuelin:array of double;

setlength (fuelin, rowcount);

while... do begin...end


 
wsv ©   (2007-07-13 12:03) [44]


> плюс ко всем тем очевидным "кривостям" и неоптимальностям
> в коде, что он привел)


Попробуйте еще как-то оптимизировать цикл while do begin end...
:-D


 
sniknik ©   (2007-07-13 12:05) [45]

> fuelin:array of double;
> setlength (fuelin, rowcount);
> while... do begin...end
ошибка. с учетом уже приведенного, у тебя теряется 2 записи. если конечно принять что курсор локальный и данные выбираются все сразу.


 
sniknik ©   (2007-07-13 12:06) [46]

> Попробуйте еще как-то оптимизировать цикл while do begin end...
я приводил то что оптимизирует этот цикл... только в данном случае конечно, но...


 
wsv ©   (2007-07-13 12:06) [47]


> ошибка. с учетом уже приведенного, у тебя теряется 2 записи.


> ЗЫ. Данные выбираются ВСЕ. Это точно. Про баги с RowCount
> я знаю и проверял на начальном этапе....
>


 
wsv ©   (2007-07-13 12:07) [48]


> я приводил то что оптимизирует этот цикл... только в данном
> случае конечно, но...
>

Эта реплика была не вам.

Вам:

> ЗЗЫ. tfield выключил. DisableControls добавил. Немного ускорилось.
>  Добавил к периоду неделю с приемлемой скоростью. За это
> СПАСИБО.


 
Сергей М. ©   (2007-07-13 12:08) [49]


> wsv ©   (13.07.07 11:59) [41]


Если известно максимальное кол-во записей, которое может оказаться в НД в рез-те выборки по известным критериям, следующие рекомендации наверняка устранят основные "тормоза":

1. Открыть однонаправленный НД.
2. Расчитать минимально необходимое кол-во памяти, необходимое для организации массива, куда будут считываться данные из НД. Выделить память.
3. В цикле while not eof do..next пройтись по НД от начала до конца, считывая данные из НД наиболее оптимальным способом и тут же подсчитывая число записей.
4. Имея фактическое число записей расчитать фактически используемую в массиве память и реаллокировать память под массив, уменьшив ее до фактического размера.


 
sniknik ©   (2007-07-13 12:12) [50]

wsv ©   (13.07.07 12:06) [47]
это к чему? потерять всего 2 записи типа для статистики неважно?
потому как если бы данные выбирались не все то потери шли бы на 0 - 98% от общего количества, в зависимости от исходного обьема.

> Эта реплика была не вам.
какая разница кому? теперь то ты говоришь
> Попробуйте еще как-то оптимизировать цикл while do begin end...
а пример подобной оптимизации уже был.


 
Anatoly Podgoretsky ©   (2007-07-13 12:30) [51]

> wsv  (13.07.2007 12:00:43)  [43]

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


 
Anatoly Podgoretsky ©   (2007-07-13 12:31) [52]

> Сергей М.  (13.07.2007 12:08:49)  [49]

Пункт 4 у него выполнен до цикла.


 
Сергей М. ©   (2007-07-13 12:40) [53]


> Anatoly Podgoretsky ©   (13.07.07 12:31) [52]
>
> > Сергей М.  (13.07.2007 12:08:49)  [49]
>
> Пункт 4 у него выполнен до цикла.
>


Я это понимаю.

Но прогрессирующие "тормоза" могут быть связаны только с одним - с перераспределением BMM-памяти при каждой итерации, что ведет к ее интенсивной дефрагментации и, как следствие, прогрессирующим замедлением работы BMM.


 
Anatoly Podgoretsky ©   (2007-07-13 12:53) [54]

> Сергей М.  (13.07.2007 12:40:53)  [53]

прогрессирующие "тормоза" вызываются двунаправленным курсором.


 
Сергей М. ©   (2007-07-13 12:56) [55]


> Anatoly Podgoretsky ©   (13.07.07 12:53) [54]


Не исключено, что на стороне Zeos-клиента использование этого курсора опять же сводится к массированному перераспределению памяти.


 
Anatoly Podgoretsky ©   (2007-07-13 13:27) [56]

> Сергей М.  (13.07.2007 12:56:55)  [55]

Все может быть, на Zeos часто ругаются, в том числе и за скорость


 
Сергей М. ©   (2007-07-13 13:40) [57]

А таки любопытно, есть ли в Мускуле IBUDF-подобный механизм..

Гуглить, честно скажу, лень)

Просветите вкратце, кто в курсе ?


 
Anatoly Podgoretsky ©   (2007-07-13 13:42) [58]

> Сергей М.  (13.07.2007 13:40:57)  [57]

MySql это несколько тысяц опубликованых версий


 
Johnmen ©   (2007-07-13 14:29) [59]


> Сергей М. ©   (13.07.07 13:40) [57]

http://www.mysql.ru/docs/man/CREATE_FUNCTION.html
дельфисты отдыхают...:)


 
Сергей М. ©   (2007-07-13 14:39) [60]


> Johnmen ©   (13.07.07 14:29) [59]


> дельфисты отдыхают


Ну глянул я на это чудо)

Да, вижу:

Чтобы механизм UDF работал, функции должны быть написаны на C или C++

Копнул чуть глубже.
Вижу что это заявление слишком громкое)


 
Johnmen ©   (2007-07-13 14:44) [61]


> Сергей М. ©   (13.07.07 14:39) [60]

Возможно. Я не копал. Мне не интересно....


 
Сергей М. ©   (2007-07-13 14:47) [62]


> Мне не интересно


Мне тоже.
Ибо любопытство удовлетворил и сделал вывод - сабж возможен, и он по механизму аналогичен IB


 
wsv ©   (2007-07-15 06:47) [63]

ВСЕМ СПАСИБО ЗА ПОНИМАНИЕ И ПОМОЩЬ, ЧОУЖ...
Разбил выбранный период на интервалы. Испытания показали, что данные за неделю (а это, по максимуму, 24 часа х 120 записей в час х 7 дней = 20800 записей) выбираются приемлемо быстро. Поэтому целый период делим на 7 дней, выбираем понедельно, потом остаток от нецелой недели. При каждом переходе в новый интервал "обнуляю" и переизмеряю массивы. Получилась своего рода "подкачка" при выборке данных.
При этом увидел плюсы:
1. При обработке добавил возможность остановить обработку, если получнные в рез-те обработки данные УЖЕ удовлетворяют, то дальше, по application.messagebox yes/no, делаем вывод о необходимости продолжения обработки.
2. Тот злополучный прогрессор теперь кажет процесс так как он есть, что говорит юзеру о том, что программа не зависла, а продолжает работать.


 
atruhin ©   (2007-07-15 09:30) [64]

> При каждом переходе в новый интервал "обнуляю" и переизмеряю
> массивы.

1. Зачем массив обнулять, если новые данные его просто перепишут? Для верности?
2. Если тебе известно максимально возможное кол-во данных за неделю, зачем изменять размер?
Один раз выделяешь массив максимального размера и все, дальше используешь Arr[0] to RowCount....

> Тот злополучный прогрессор теперь кажет процесс так как он есть

Тебе не предлагили отказаться от прогрессбара. Предлагали сделать размер прогрессбора например RowCount div 100.
Далее if CurrentRow div 100 = 0 then pb.StepBy(1);
Это все твои тормоза.
Ну и самое важное, тебе все говорят про однонаправленный курсор, зачем игнорируешь?


 
Artyom789123 ©   (2007-07-25 02:23) [65]

to wsv ©
Проблема та же...
но есть отличия - всё гораздо хуже, поэтому хотелось бы больше подробностей.
>>что данные за неделю (а это, по максимуму, 24 часа х 120 записей в час х >>7 дней = 20800 записей) выбираются приемлемо быстро.
У неприемлимо медленно:

13000 - 37 секунд, 26200 - 153, 39600 - 362

Времена варьируюься в зависимости от мощности компьютера и mysql-сервера (localhost -задержка в доли секунды, DSL - десятки секунд).
Подробностями в данном случае я подразумеваю тип процессора, объём RAM, версию SQL и Zeos, размер строки таблицы и т.п.

to atruhin
>>Это все твои тормоза.

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



Страницы: 1 2 вся ветка

Форум: "Базы";
Текущий архив: 2007.12.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.63 MB
Время: 0.045 c
15-1193493795
Denis__
2007-10-27 18:03
2007.12.02
Aнимация


15-1193506385
Parus
2007-10-27 21:33
2007.12.02
telnet server под linux


15-1194092585
Kostafey
2007-11-03 15:23
2007.12.02
NOOOXML


1-1189580697
cantalia
2007-09-12 11:04
2007.12.02
Событие из DLL в Main Application


15-1193421519
Vendict
2007-10-26 21:58
2007.12.02
Географические координаты в метры





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский