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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.10.2011, 13:30   #1
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию запрос с параметрами

Есть часть кода:
Код:
       for j:=0 to IBQuery2.RecordCount-1 do  begin
         MATCOUNT:= trim(IBQuery2.FieldByName('TCOUNT').AsString);
         GTDSPRAVNO:= trim(IBQuery2.FieldByName('GTDSPRAVNO').AsString);
         GTDRAZR:= trim(IBQuery2.FieldByName('GTDRAZR').AsString);
         IMPGTDNO:= trim(IBQuery2.FieldByName('IMPGTDNO').AsString);
         IMPGTDNOOSN:= trim(IBQuery2.FieldByName('IMPGTDNOOSN').AsString);
          if StrToInt(IMPGTDNOOSN) = i then
            begin
              IMPGTDNO2:= IMPGTDNOOSN;
              GTDSPRAVNO2:= GTDSPRAVNO;
              with IBQuery4 do begin
                  Close;
                  Params[0].AsString:=IMPGTDNO;
                  Params[1].AsString:=GTDRAZR;
                  Open;
                  FetchAll;
                end;
              mat_costone:= ((StrToFloat(IBQuery4.Fields[1].Value))/(StrToFloat(IBQuery4.Fields[0].Value)))*StrToFloat(MATCOUNT);
              matprod:= matprod + mat_costone;
            end;
         IBQuery2.Next;
       end;
Есть ли возможность вынести часть с выполнением IBQuery4 за пределы цикла, если эти 2 параметра изменяются с каждой итерацией цикла? Не уверен, что это вообще можно сделать, т.к. с запросами с параметрами не особо знаком. И может будут другие советы, как увеличить быстродействие этого куска кода? Спасибо.
chui вне форума Ответить с цитированием
Старый 26.10.2011, 20:35   #2
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Хотелось бы понять какой смысл вложен в этот кусок кода, если значения переменных mat_costone и matprod в каждой итерации заменяются, но не используются.
И что дальше?
Прик вне форума Ответить с цитированием
Старый 26.10.2011, 23:10   #3
Dush
Форумчанин
 
Регистрация: 29.09.2011
Сообщений: 116
По умолчанию

по вопросу оптимизации: если возможно менять структуру таблиц базы то я бы предложил изменить тип полей, которые вы считываете из IBQuery2, на integer и numeric. таим образом можно избавится от Trim и StrToInt/StrToFloat. Прийдется добавить проверку значений при внесении их в базу, но при большом количестве записей уменьшится время на их считывание обработку. но, по идее, при внесении этих значений в базу вы и так должны делать проверку на соответствие формата.
а если касаться запроса с параметрами то не видя самого запроса, не зная структуру базы нельзя ничего оптимизировать.
по приведенному коду не понять логики выборок. тут я согласен с Прик.
Dush вне форума Ответить с цитированием
Старый 27.10.2011, 00:16   #4
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

Прик, из этого куска кода мне необходимо итоговое значение переменной matprod после завершения цикла.
Dush, спасибо за совет, но программа значительно тормозит именно на запросе (Open). Ниже текст запроса.

Код:
SELECT TOV_COUNT,TOV_COST
from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID) 
where (TOV_IMPGTDNO =:param1)  and (GTDRAZR =:param2)
chui вне форума Ответить с цитированием
Старый 27.10.2011, 00:45   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Тяжело разобраться не имея понятия о структуре задействованных таблиц и связи между ними, но смею предположить, что данный расчет можно попытаться выполнить на уровне запроса. Кидайте сюда структуры таблиц и внятное описание того, что нужно сделать, возможно и получится. А то как вы в цикле выполняете обращение к базе при всех ухищрениях будет очень тормозить. Не забудьте упомянуть какая СУБД. Хотя вижу, Интербейс
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 27.10.2011 в 00:48.
Аватар вне форума Ответить с цитированием
Старый 27.10.2011, 04:43   #6
Surgeon
Форумчанин
 
Регистрация: 04.10.2007
Сообщений: 106
По умолчанию

Ускорить можно:
- использовать метод IBQuery.Prepare
- создать индекс по полям к которым относятся параметры
Все не так плохо, как вам кажется, на самом деле все гораздо хуже.
http://delphiworld.narod.ru/dw.html - 5000 статей!!! удобный поиск, оффлайн сборник, рекомендую всем
Surgeon вне форума Ответить с цитированием
Старый 27.10.2011, 05:13   #7
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Думается, еще быстрее будет, если переделать эти расчеты в запрос, отправить его выполняться на сервер СУБД и получить от него то самое нужное единственное значение.
Прик вне форума Ответить с цитированием
Старый 27.10.2011, 10:37   #8
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

Спасибо за советы. Сейчас попробую описать более подробно.
Код:
   for i:= 1 to maxi do begin
       IBQuery2.First;
       for j:=0 to IBQuery2.RecordCount-1 do  begin
         MATCOUNT:= trim(IBQuery2.FieldByName('TCOUNT').AsString);
         GTDSPRAVNO:= trim(IBQuery2.FieldByName('GTDSPRAVNO').AsString);
         GTDRAZR:= trim(IBQuery2.FieldByName('GTDRAZR').AsString);
         IMPGTDNO:= trim(IBQuery2.FieldByName('IMPGTDNO').AsString);
         IMPGTDNOOSN:= trim(IBQuery2.FieldByName('IMPGTDNOOSN').AsString);
          if StrToInt(IMPGTDNOOSN) = i then
            begin
              IMPGTDNO2:= IMPGTDNOOSN;
              GTDSPRAVNO2:= GTDSPRAVNO;
              with IBQuery4 do begin
                  Close;
                  Prepare;
                  Params[0].AsString:=IMPGTDNO;
                  Params[1].AsString:=GTDRAZR;
                  Open;
                  FetchAll;
              end;
              mat_costone:= ((StrToFloat(IBQuery4.Fields[1].Value))/(StrToFloat(IBQuery4.Fields[0].Value)))*StrToFloat(MATCOUNT);
              matprod:= matprod + mat_costone;
            end;
         IBQuery2.Next;
       end;
        with IBQuery5 do begin
          Close;
          Params[0].AsString:=IMPGTDNO2;
          Params[1].AsString:=GTDSPRAVNO2;
          Open;
          FetchAll;
        end;
        prod_cost:= StrToFloat(IBQuery5.Fields[0].Value);
        if (prod_cost/matprod)<2 then  begin
            SZForm.AddLog('Плохо');
           end else inc(err_c);
        matprod:= 0;
        ProgressBar1.Position:= i;
        ProgressBar1.Update;
     end;
Данные загружаются во временную таблицу (IBQuery2) из xml файла. После чего мне нужно произвести расчет matprod и сравнить его с prod_cost. Чтобы произвести расчет используются 2 таблицы T_Tovar и T_Gtd, из которых получаю необходимые данные для расчета. БД в FireBird.

Surgeon, я попытался использовать Prepare, но скорость не изменилась. Как правильно его использовать?
chui вне форума Ответить с цитированием
Старый 27.10.2011, 11:33   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Вариант1. Загнать данные из xml в базу и попытаться одним запросом решить.
Вариант2. Вытащить один раз нужную инфу из базы, пусть даже ее очень много и с избытком, но не делать запросы в цикле
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 27.10.2011, 18:09   #10
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

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


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

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запрос с параметрами us4us SQL, базы данных 1 20.05.2011 05:53
программа с типизированными параметрами-значениями и параметрами-переменными Kira09 Паскаль, Turbo Pascal, PascalABC.NET 1 20.12.2010 22:23
Запрос с CASE переделать в запрос с PIVOT (MS SQL Server 2005) Машуля SQL, базы данных 4 06.05.2010 21:09
Запрос с изменяющимися параметрами GenniY БД в Delphi 10 18.03.2010 14:41