Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 03.07.2013, 20:50
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию Delphi + Firebird альтернатива функции Locate

Здравствуйте, направьте пожалуйста на путь истинный.

База данных FireBird есть таблица с ключевым полем. Нужно перенести курсор в dbgrid на строку с определенным id
обычно выполняю это так:

dtmdlMain.ibqryViewUsluga.Locate('USLUGA_ID',uslID ,[]);
frmMain.dbgrdhMain.SetFocus;

при таблице в среднем в 400 записей locate проводится до 3 секунд на слабой машине. (проблема в том что база быстро увеличивается, соответственно время так же).

Есть ли альтернатива данному методу?

delphi xe2
Ответить с цитированием
  #2  
Старый 03.07.2013, 22:25
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Попробуйте Seek использовать.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 04.07.2013, 06:23
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию

Seek для работы с бинарными файлами как я понял а не с бд
Ответить с цитированием
  #4  
Старый 04.07.2013, 09:05
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Ravennt
Seek для работы с бинарными файлами как я понял а не с бд

попробуй отключать DB Aware компоненты на момент поиска - TIBQuery.DisableControls/TIBQuery.EnableControls.

Хотя это сильно не должно влиять. Что-то странное, поиск в 400 записях - не самая сложная задача. 3 сек на нее - очень долго...
Ответить с цитированием
  #5  
Старый 04.07.2013, 09:09
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Как вариант -- перестать использовать TIBTable и написать, наконец, нормальную программу.
Ответить с цитированием
  #6  
Старый 04.07.2013, 10:18
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию

Я не использую ibtable, для подключения к firebird base использую такие компоненты
TIBDatabase - TIBquery - TIBTransaction - TDateSource.

TIBQuery.DisableControls/TIBQuery.EnableControls эффекта не дает, проблемма с медленным Locate имеет место быть, но так в интернете метода решения проблемы не нашел. Только лишь переход на FIBPlus компоненты, но переписывать всю программу сомнительный вариант.

может еще кто знает как возможно в дбгриде перенести курсор на определенную запись не используя Locate?
Ответить с цитированием
  #7  
Старый 04.07.2013, 10:50
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Тогда, скорее всего, у TIBQuery есть какие-то события, выполняющиеся для каждой записи, они и тормозят. Попробуй для начала выполнить Locate на чистом запросе.
Ответить с цитированием
  #8  
Старый 04.07.2013, 10:55
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Да, действитеьно в IB нет Seek. Как-то и не знал об этом.
Я предположу, что у вас индексы не определены, хотя даже без индекса и для 4000 записей не должно быть такой задержки.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #9  
Старый 04.07.2013, 11:36
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Страдалецъ
Я предположу, что у вас индексы не определены, хотя даже без индекса и для 4000 записей не должно быть такой задержки.
Причем тут индексы и где они на клиенте? Это же не dBase и не Clipper тебе. Хоть бы в реализацию TIBCustomDataSet.Locate посмотрел.
Ответить с цитированием
  #10  
Старый 04.07.2013, 11:48
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию

Цитата:
Сообщение от Freeman
Тогда, скорее всего, у TIBQuery есть какие-то события, выполняющиеся для каждой записи, они и тормозят. Попробуй для начала выполнить Locate на чистом запросе.

вот сам текст запроса

Код:
select 
    clients_table.fio,
    clients_table.fdate,
    usluga_table.pdate,
    usluga_table.time_start,
    clients_table.address,
    usluga_table.time_end,
    usluga_table.target_name,
    status_table.fstatus,
    usluga_table.kolvo_uslug,
    usluga_table.group_usluga,
    usluga_table.usluga_id,
    usluga_table.client
from usluga_table
   inner join status_table on (usluga_table.status_usluga = status_table.status_id)
   inner join clients_table on (usluga_table.client = clients_table.clients_id)
   where usluga_table.group_usluga = 0
   order by usluga_table.pdate, usluga_table.time_start, clients_table.fio
по этому запросу делаю Locate по полю usluga_table.usluga_id

usluga_table.usluga_id это одно поле из главной таблицы, и на ibquery событий не навешано.

Последний раз редактировалось Ravennt, 04.07.2013 в 11:54.
Ответить с цитированием
  #11  
Старый 04.07.2013, 11:59
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

может всё-таки есть смысл не выводить все данные, а изначально отобрать нужные и потом бегать по Locate?
ps. а вообще перейди на компоненты FIB+ ... они пошустрее будут.
ps2. и да, как подсказал lmikle: перед началом locate делать DisableControls и после него EnableControls
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз
Ответить с цитированием
Этот пользователь сказал Спасибо Yurk@ за это полезное сообщение:
Ravennt (04.07.2013)
  #12  
Старый 04.07.2013, 12:02
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

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

Цитата:
Сообщение от Yurk@
ps2. и да, как подсказал lmikle: перед началом locate делать DisableControls и после него EnableControls
Locate сам это делает.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
Этот пользователь сказал Спасибо Aristarh Dark за это полезное сообщение:
Ravennt (04.07.2013)
  #13  
Старый 04.07.2013, 12:12
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию

я формирую уже конкретно таблицу с необходимыми данными для просмотра.

DisableControls и после него EnableControls -- эффекта не дает.
Ответить с цитированием
  #14  
Старый 04.07.2013, 12:16
Ravennt Ravennt вне форума
Прохожий
 
Регистрация: 10.09.2012
Сообщения: 19
Репутация: 10
По умолчанию

Цитата:
Сообщение от Aristarh Dark
Locate, если мне не изменяет мой склероз, это простой перебор записей сверху вниз до тех пор пока не найдем нужную. Напиши сам такой перебор, возможно он будет работать быстрее потому как в "родном" скорее всего учитываются типы полей и т.п. из-за чего происходит замедление процесса.

писал вот такое эффекта не дало
Код:
//поиск по полю
procedure LocateTable(w:TIBQuery; Pole:String;Znachen:Integer);
begin
  try
    w.Close;
    w.Open;
    w.FetchAll;
    w.First;
    while not w.Eof do begin
      if w.FieldByName(''+Pole+'').AsInteger=Znachen then
        Exit;
      w.Next;
    end;
  except
    on E: Exception do
      begin
        Application.MessageBox(PChar(E.Message), 'Ошибка', MB_ICONERROR);
        w.Close;
        Halt;
      end;
  end;
end;
Ответить с цитированием
  #15  
Старый 04.07.2013, 12:32
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Ravennt
usluga_table.usluga_id это одно поле из главной таблицы, и на ibquery событий не навешано.
Тогда могу предложить лишь следующее:
  • Попробовать вызвать FetchAll после открытия запроса.
  • Пройтись отладчиком, чтобы убедиться, что тормозит именно на Locate. Если это именно так, пройтись отладчиком, входя в исходники TIBCustomDataSet, чтобы выяснить, какая строчка выполняется дольше всего.
Я посмотрел в исходниках TIBCustomDataSet.Locate и ничего крамольного не нашел. Записей точно 400, а не 400000, например?

Возможно, существуют какие-то профилировщики под Delphi, но пользоваться не приходилось. Тут, скорее, дело именно в вызывающем коде, а не самом компоненте TIBQuery.

Покажите заодно строчку с вызовом Locate.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:03.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter