Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.12.2011, 11:25   #1
{Shadowevil}
Пользователь
 
Регистрация: 15.01.2009
Сообщений: 52
По умолчанию Загрузка таблицы в память

Здравствуйте! Подскажите пожалуйста ответ. У меня есть БД из нескольких таблиц, возможно ли загрузить одну из таблиц в оперативную память чтобы сократить время обращения к ее данным? Я почитал что есть такая вещь как TBucketList с помощью которой можно имитировать ассоциативный массив, может кто нибудь встречался с такой проблемой?
{Shadowevil} вне форума Ответить с цитированием
Старый 21.12.2011, 19:08   #2
alexiz
Пользователь
 
Регистрация: 19.08.2010
Сообщений: 54
По умолчанию

Цитата:
Сообщение от {Shadowevil} Посмотреть сообщение
возможно ли загрузить одну из таблиц в оперативную память чтобы сократить время обращения к ее данным?
Смотря какая там таблица. Базы данных тоже не зря придумывали.
Однако, если таблица небольшая (примерно до 1000 записей), конечно можно. Например RxMemoryData компонент умеет прочитать данные из Датасета в свой буфер и потом изображать, что он и есть Датасет со всеми положенными свойствами, БД при этом далее не нужна. (Библиотека Rx).
Ваша благодарность может быть материальной:
WM R103871054215, WM Z710411027344, ЯндД: 410011167596676
alexiz вне форума Ответить с цитированием
Старый 21.12.2011, 19:19   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Что-то не пойму проблемы. Данные активизированных ADOQuery или ADOTable и так находятся в памяти. Доступ к данным конечно не такой, как к массиву в памяти. Или вам нужен массив из Record-ов с доступом по индексу? Или проблема в доступе к данным после закрытия DataSet? Если вы данные каким-то образом перетяните в массив, то по памяти почти не сэкономите. По скорости доступа можно будет сэкономить, если загрузка в реальный массив и доступ по индексу, который кстати и знать нужно будет. В противном случае существенной экономии не получите, даже воспользовавшись компонентом типа RxMemoryData или ему подобным
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.12.2011, 07:10   #4
{Shadowevil}
Пользователь
 
Регистрация: 15.01.2009
Сообщений: 52
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Что-то не пойму проблемы. Данные активизированных ADOQuery или ADOTable и так находятся в памяти. Доступ к данным конечно не такой, как к массиву в памяти. Или вам нужен массив из Record-ов с доступом по индексу? Или проблема в доступе к данным после закрытия DataSet? Если вы данные каким-то образом перетяните в массив, то по памяти почти не сэкономите. По скорости доступа можно будет сэкономить, если загрузка в реальный массив и доступ по индексу, который кстати и знать нужно будет. В противном случае существенной экономии не получите, даже воспользовавшись компонентом типа RxMemoryData или ему подобным
Честно даже не знаю как правильно сформулировать. Если Вы помните, Вы помогли мне нарисовать на канве ListBox'a текст из БД, так вот, в том же событии onDrawItem имеется тот самый код, выбирающий необходимую запись в зависимости от индекса итема, а дальше запрос, выбирающий из другой таблицы (в моем случае "Phone") необходимые записи, где в качестве параметров выступают значения из ZQuery1, когда итемов получается допустим 5, то все нормально, а когда 25 то при перемотке канвы появляются артефакты из-за постоянного обращения к БД(т.к. итемы на канве постоянно перерисовываются), меня интересует возможно ли предварительно загрузить таблицу Phone в память и обращаться к памяти, а не к самой БД??
Код:
  ZQuery1.RecNo:=Integer(sListBox1.Items.Objects[Index]);
...
...
Query10.SQL.Clear;
  Query10.SQL.Add('SELECT who, code, phone FROM phone WHERE cid=:cityid AND fid=:fid');
 Query10.ParamByName('cityid').Value:=ZQuery1.FieldByName('cid').AsInteger;
  Query10.ParamByName('fid').Value:=ZQuery1.FieldByName('fid').AsInteger;
  Query10.Open;
  While Not Query10.Eof do
   begin
    str:=Query10.FieldByName('who').AsString;
    if str='' then str:=' ' else str:=str+': ';
    st:=st+str+'8 '+'('+Query10.FieldByName('code').AsString+') '+Query10.FieldByName('phone').AsString+'; ';
    Query10.Next;
   end;
 ...

Последний раз редактировалось {Shadowevil}; 22.12.2011 в 07:13.
{Shadowevil} вне форума Ответить с цитированием
Старый 22.12.2011, 08:59   #5
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

покажи как ресуешь конечного варианта в прошлой ветки не увидел
а лучше весь листинг в студию
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 22.12.2011, 09:02   #6
{Shadowevil}
Пользователь
 
Регистрация: 15.01.2009
Сообщений: 52
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
покажи как ресуешь конечного варианта в прошлой ветки не увидел
а лучше весь листинг в студию
Весь листинг слишком здоровый, да и не к чему в принципе, вот прорисовка:
Код:
procedure TfrmMain.sListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  xColor: TColor;
  x, i,k,h: integer;
  str, st, st2: string;
begin
  if sListBox1.Count=0 then Exit;
  ZQuery1.RecNo:=Integer(sListBox1.Items.Objects[Index]);

  st:=sListBox1.Items.Strings[Index];
  i:=Pos('^', st);
  k:=Pos('&', st);
  st2:='';
  for i:=i+1 to k-1 do
    st2:=st2+st[i];
  LBfid:=strtoint(st2);
  i:=Pos('^', st);
  st2:='';
  for k:=1 to i-1 do
    st2:=st2+st[k];


  if (odSelected in State) and sListBox1.Focused then xColor:=clActiveCaption
  else if odSelected in State then xColor:=clBtnFace
  else xColor:=clWindow;
  sListBox1.Canvas.Brush.Color:=clWindow;
  sListBox1.Canvas.FillRect(Rect);

  if (odSelected in State) and Control.Focused then sListBox1.Canvas.Font.Color:=clGradientActiveCaption
  else sListBox1.Canvas.Font.Color:=clBlack;  

  sListBox1.Canvas.Font.Size:=9;
  x:=sListBox1.Canvas.Font.Size;
  sListBox1.Canvas.TextRect(Rect, Rect.Left+10,Rect.Top, st2);
  sListBox1.Hint:=st2;
  sListBox1.ShowHint:=true;

  i:=Pos('&', st);
  st2:='';
  for i:=i+1 to Length(st) do
    st2:=st2+st[i];
  LBadr_id:=strtoint(st2);

 if (odSelected in State) and Control.Focused then sListBox1.Canvas.Font.Color:=clInactiveCaption
  else
  sListBox1.Canvas.Font.Color:=clGray;
  sListBox1.Canvas.Font.Size:=8;

  sListBox1.Canvas.TextOut(Rect.Left+15, Rect.Top+x+7, ZQuery1.FieldByName('allinfo').AsString);

   
  st:='';
  Query10.SQL.Clear;
  Query10.SQL.Add('SELECT who, code, phone FROM phone WHERE cid=:cityid AND fid=:fid');
  Query10.ParamByName('cityid').Value:=ZQuery1.FieldByName('cid').AsInteger;
  Query10.ParamByName('fid').Value:=ZQuery1.FieldByName('fid').AsInteger;
  Query10.Open;
  While Not Query10.Eof do
   begin
    str:=Query10.FieldByName('who').AsString;
    if str='' then str:=' ' else str:=str+': ';
    st:=st+str+'8 '+'('+Query10.FieldByName('code').AsString+') '+Query10.FieldByName('phone').AsString+'; ';
    Query10.Next;
   end;
   sListBox1.Canvas.TextOut(Rect.Left+15, Rect.Top+x+23, 'тел: '+st);
end;
{Shadowevil} вне форума Ответить с цитированием
Старый 22.12.2011, 09:45   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Ну и зачем при прорисовке каждый раз запрос выполнять? Если не получилось эти данные засунуть в общий запрос, о котором шел разговор в конце прошлого поста, то в тот же Query10 там же потяните все данные из phone без условия WHERE, но с ORDER BY cid,fid. При прорисовке используя Query10.Locate и данные из записи ZQuery1 находите первую строку и остальные в цикле
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.12.2011, 10:10   #8
{Shadowevil}
Пользователь
 
Регистрация: 15.01.2009
Сообщений: 52
По умолчанию

Так надо делать? вместо Query10 - ZQuery3
Код:
ZQuery3.Locate('fid', ZQuery1.FieldByName('fid').AsInteger, [loPartialKey]);
{Shadowevil} вне форума Ответить с цитированием
Старый 22.12.2011, 11:01   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

С учетом ORDER BY cid,fid
Код:
  if ZQuery3.Locate('cid;fid',VarArrayOf([ZQuery1.FieldByName('cid').AsInteger,ZQuery1.FieldByName('fid').AsInteger]),[]) then
    while not ZQuery3.eof and 
          (ZQuery3.FieldByName('cid').AsInteger=ZQuery1.FieldByName('cid').AsInteger) and
          (ZQuery3.FieldByName('fid').AsInteger=ZQuery1.FieldByName('fid').AsInteger) do begin
      ...
      ZQuery3.Next;
    end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.12.2011, 11:11   #10
{Shadowevil}
Пользователь
 
Регистрация: 15.01.2009
Сообщений: 52
По умолчанию

Спасибо, сделал) только вот практически ничего не изменилось (
А можно как нибудь ускорить процесс прорисовки канвы?
{Shadowevil} вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DBImage загрузка из Таблицы Elementery Общие вопросы Delphi 9 13.06.2013 21:52
Загрузка программы в память CodeNOT Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 10 13.12.2011 23:58
Загрузка данных из таблицы Vladuk БД в Delphi 1 24.04.2011 20:16
Набор данных и загрузка другой таблицы Turbine БД в Delphi 1 21.03.2011 14:26
Загрузка данных и построение таблицы. Lisichka Microsoft Office Word 12 04.02.2009 15:31