Небольшой вопрос по поводу баз данных с fcl-db

Модератор: Модераторы

Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hinst » 30.12.2013 19:11:04

Когда получаешь данные с TQuery, TSQLConnection и прочими, вот в экземпляре TQuery вызываешь метод Next. Вопрос вот в чём: при этом все данные получаются все сразу, и я потом только их перебираю, или же они получаются некими порциями, по одной штуке, скажем, а потом освобождаются?
То есть, если у меня в таблице 1000000000...... записей, я их запрошу и начну перебирать, то они все сразу придут и будут все в памяти висеть пока не закроешь query, или они будут по частям приходить, и уже просмотренные будут освобождаться?
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hovadur » 04.01.2014 20:31:42

Я не смотрел именно TSQLQuery (только TZQuery из Zeoslib), но записи должны приходить частями. Сколько записей в одной части задается в TZQuery настройкой FetchRow. Аналогичная настройка должна быть и в TSQLQuery и похоже это PacketRecords.
Просмотренные записи не освобождаются.
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hinst » 09.01.2014 14:05:05

Получается как-то немного тупо. Когда в Query перебираешь полученные записи методом Next, то предыдущие уже просмотренные должны освобождаться, к ним же всё равно нельзя вернуться, метода Back или Previous нету
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение sim-sim » 09.01.2014 21:13:25

Prior не оно ?

Получается как-то немного тупо
скоко лет уже этому и вроде никто не жаловался...
Данные загружаются порциями (можно и все сразу) и остаются до... того времени пока они Вам не нужны. Как то так. По крайней мере - основы SQl вроде как...
sim-sim
новенький
 
Сообщения: 11
Зарегистрирован: 27.12.2013 22:44:48

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hinst » 10.01.2014 00:17:38

Я вот что имею в виду:::
Код: Выделить всё
var
  q: TQuery;
begin
  ...
  a := q.FieldByName("a").AsString;
  q.Next;
  a := q.FieldByName("a").AsString;
  q.Next;
  a := q.FieldByName("a").AsString;
  ...

Вот в этом примере результат загружается в переменную a, потом она затирается....
Если я таким образом буду просматривать триллиард записей, то это будет долго, но с памятью проблем быть не должно, так как предыдущие результаты я не храню. Вопрос в том, хранятся ли они где-то на уровне fcl-db? Я не храню предыдущие a, но я не знаю, хранятся ли они где-то в реализации класса TQuery или вообще по логике модулей fcl-db. Надеюсь стало понятно что я имею в виду.

В случае если предыдущие записи не хранятся, то просмотр записей с отбрасыванием предыдущих результатов сработает. В случае же если предыдущие записи хранятся,,, то не смотря на то что в _моём_ коде они не хранятся _явно_, памяти при большом количестве записей может не хватить, ок да.....

Добавлено спустя 1 минуту 42 секунды:
я имею в виду fcl-db предыдущие записи хранит или нет. Понятно по крайней мере что все записи сразу не загружаются. Они загружаются постепенно. Вопрос в том, освобождаются ли они постепенно
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение sim-sim » 10.01.2014 00:57:40

если память не изменяет то данные остаются у вас до момента когда коннект OFF (т.е. они не нужны).

Т.е. то что вытянули осталось в датасете... Память "отжираетса" в зависимости от их количества. О "очистке" данных после получения не слышал (и не встречал). Да и по логике - зачем их очищать (вдруг понадобятся). Вот когда конект оф тогда и удаляются данные.

Хотя, может существуют просвещенные более чем я :) Исправите...

памяти при большом количестве записей может не хватить

угу...

Вот в этом примере результат загружается в переменную a, потом она затирается.


Если загружать порциями то не будет никаких "загрузок" памяти.

К примеру: загрузили 100 записей, обработали, полезли за новыми (предварительно "очистив" датасет от предыдущих).

п.с.

основы SQl вроде как

упс: основы баз данных :)
sim-sim
новенький
 
Сообщения: 11
Зарегистрирован: 27.12.2013 22:44:48

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hinst » 10.01.2014 23:05:09

sim-sim писал(а):Если загружать порциями то не будет никаких "загрузок" памяти.
К примеру: загрузили 100 записей, обработали, полезли за новыми (предварительно "очистив" датасет от предыдущих).

Что-то я не понимаю, как это реализовать.
Вот я делаю например запрос select * from Table1; потом делаю query.Next в цикле, а как сделать загрузку по 100 записей, например, я что-то не понимаю. Можно в двух словах плз?
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение sim-sim » 10.01.2014 23:34:39

двух словах плз


эээх-ух и ах

Кратко. http://freepascal.ru/article/lazarus/20090720000443/ а более подробно - гугл :)
sim-sim
новенький
 
Сообщения: 11
Зарегистрирован: 27.12.2013 22:44:48

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение EmeraldMan » 11.01.2014 12:01:12

hinst писал(а):Получается как-то немного тупо. Когда в Query перебираешь полученные записи методом Next, то предыдущие уже просмотренные должны освобождаться, к ним же всё равно нельзя вернуться, метода Back или Previous нету

Как так нету?
SQLQuery.Next; SQLQuery.Prior; а так же SQLQuery.First и SQLQuery.Last. Можно воспользоваться ещё и SQLQuery.MoveBy(Num);

Причем обнаружил интересную особенность: бывает, что когда делаешь большую выборку, то SQLQuery.RecordCount показывает явно меньшее кол-во записей. А если выполнить "SQLQuery.Last; SQLQuery.First;", а затем запросить SQLQuery.RecordCount, то покажет точное число.
Аватара пользователя
EmeraldMan
постоялец
 
Сообщения: 149
Зарегистрирован: 16.10.2008 08:41:51
Откуда: Белгород

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение VirtUX » 04.03.2014 21:24:53

Есть-ли возможность получить одной строкой (с разделителями полей) данные текущей записи?
TSQLQuery.GetCurrentRecord(p: pansichar) - может это как-то можно преобразовать в строку?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение hovadur » 04.03.2014 21:41:36

VirtUX писал(а):Есть-ли возможность получить одной строкой (с разделителями полей) данные текущей записи?

Код: Выделить всё
s := '';
for i := 0 to Query.FieldDefs.Count -1 do begin
  if s= '' then
    s := Query.Fields[i].AsString
  else
    s := s + ';' + Query.Fields[i].AsString;
end;
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение VirtUX » 04.03.2014 23:37:05

2 hovadur я не про это спрашивал. А про:
Код: Выделить всё
for i := 1 to Query.RecordCount do begin
  s += Query.(Record целиком с разделителями полей) + Char(Разделитель записей);
end;
Delete(s, length(s), 1)


Добавлено спустя 2 минуты 33 секунды:
Перерыл код, и закралось подозрение, что TSQLQuery.GetCurrentRecord(p: pansichar) - не реализовано. Т.к кроме как в предке TDataset (begin Result := false; end;), больше переопределений нет :(
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение debi12345 » 04.03.2014 23:51:26

TQuery вызываешь метод Next. Вопрос вот в чём: при этом все данные получаются все сразу, и я потом только их перебираю, или же они получаются некими порциями, по одной штуке,

Это называется вроде как "window" (сопрягается с БД-курсором) - больное место DB-компонентов. Если вытаскивать все записи - в плюсах имеешь точное количество записей, правильную навигацию и скроллинг - но может не хватить памяти и уведешь комп в крайне тормознутый своппинг ( особенно если таких прожорливых компонентов много).
В MSE, после жалоб на кривой дельфевский скроллинг в БД-гридах и списках - даже пришлось реализовывать оба варианта - если приаттаченные компоненты для корректного скроллинга требуют всех записей, то вытаскиваются все. Если не требуются - вытаскивается и обновляется только "window".

Query.RecordCount

Чрезвычайно медленная операция в FCL-DB, потому что записи здесь, из соображения поддержания "window - представлены связанным списком, и узнать их количество можно только дойдя до последнего элемента этого списка.
Чтобы этого избежать, например в MSE список заменили на динамический массив записей фиксированного размера (вместо строк хранятся их указатели).

Добавлено спустя 57 минут 10 секунд:
SQLQuery.GetCurrentRecord(p: pansichar) - может это как-то можно преобразовать в строку?

Там может быть куча бинарных данных -как их преобразуешь ?

как сделать загрузку по 100 записей,


SQL :
Код: Выделить всё
select * from Table1 OFFSET x LIMIT y;


или "window"
Код: Выделить всё
query.FetchRows := y;

?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение MaratIsk » 05.03.2014 07:38:09

hinst писал(а):Получается как-то немного тупо. Когда в Query перебираешь полученные записи методом Next, то предыдущие уже просмотренные должны освобождаться, к ним же всё равно нельзя вернуться, метода Back или Previous нету


unidirectional
MaratIsk
постоялец
 
Сообщения: 117
Зарегистрирован: 20.08.2009 18:15:20

Re: Небольшой вопрос по поводу баз данных с fcl-db

Сообщение wavebvg » 05.03.2014 18:04:42

Есть - TDataSet - класс (в общем-то, абстракный), предназначен для именованного доступа к набору данных (никаких связанных списков и прочей ереси для "ускорения" - только структура и данные, которые читаются лишь в тот момент, когда нужны).
TQuery - реализация это доступа с использованием TSQLConnection (естественно, с буферизацией)

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

Если Вы хотите реализовать более "оптимальную" работу с памятью, то придётся разобраться с тем, как устроены эти компоненты и реализовать свой собственный "умный буфер".

Проблема с "неверным" количеством записей возникает для случаев, когда получение данных ещё не завершено (сервер их тоже не загрузил ещё не знает). Фича очень удобна при работе с большими объемами данных (в частности, обеспечивает возможность по индексам получить большую выборку и потом со смаком её тянуть с сервера не вляпываясь в полное зависание базы и прочие недоразумения) или получать только первые данные, когда все сразу они явно не нужны, а сервак тогда сможет обработать намного больше клиентов. Чтобы этого избежать, нужно сразу фечить все данные.
wavebvg
постоялец
 
Сообщения: 354
Зарегистрирован: 28.02.2008 04:57:35

След.

Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

Рейтинг@Mail.ru