Конференция "Базы" » Помогите оптимизировать запрос (D2007, BDE, Paradox) [Paradox]
 
  • petvv (28.11.08 09:25) [0]
    В общем есть такой код:

    procedure TMainForm.GetCena;
    begin
     Cena.Active:=False;
     Cena.SQL.Clear;
     Cena.SQL.Add('select price from Statist where Statist.DateTime<:QDBeg and Statist.Product='+IntToStr(Temp.FieldByName('Product').Value) +' and Statist.Osnovanye=0');
     Cena.ParamByName('QDBeg').AsDateTime:=Temp.FieldByName('DateTime').Value;
     Cena.Active:=True;
     Cena.RecordCount;
     Cena.FindLast;
     Cena1:=Cena.FieldByName('Price').Value;
     Cena.Close;
    end;

    procedure TMainForm.btnStartClick(Sender: TObject);
    begin
    DT;
     if DEnd<DBeg then
       begin
         MessageBox(0,'Дата окончания периода меньше даты начала периода !','Неверныё период расчётов',0);
         Exit;
     end;
    qOsn.Close;
    qOsn.Params[0].AsDateTime:=DBeg;
    qOsn.Params[1].AsDateTime:=DEnd;
    qOsn.Active:=True;
    //********************************
    Temp.Active:=False;
    Temp.DataBaseName:='STATION32';
    Temp.TableName:='Temp';
    Temp.TableType:=ttParadox;
    Temp.FieldDefs.Clear;
    Temp.FieldDefs.Add('DateTime',ftDateTime);
    Temp.FieldDefs.Add('Marka',ftString,50,False);
    Temp.FieldDefs.Add('Product',ftFloat,0,False);
    Temp.FieldDefs.Add('Osnovan',ftString,50,False);
    Temp.FieldDefs.Add('Osnovanye',ftFloat,0,False);
    Temp.FieldDefs.Add('Litr',ftFloat,0,False);
    Temp.FieldDefs.Add('Summa',ftFloat,0,False);
    Temp.FieldDefs.Add('Price',ftFloat,0,False);
    Temp.FieldDefs.Add('Delta',ftFloat,0,False);
    Temp.FieldDefs.Add('Report',ftBoolean,0,False);
    Temp.FieldDefs.Add('Discount',ftBoolean,0,False);
    Temp.CreateTable;
    Temp.Active:=True;
    Temp.Edit;
    Temp.First;
    for n:=1 to qOsn.RecordCount do begin
     Temp.Append;
     Temp.FieldByName('Product').AsString:=qOsn.FieldByName('Product').Value;
     Temp.FieldByName('Osnovanye').AsString:=qOsn.FieldByName('Osnovanye').Value;
     Temp.FieldByName('Discount').AsString:=qOsn.FieldByName('Discount').Value;
     Temp.FieldByName('DateTime').AsDateTime:=qOsn.FieldByName('DateTime').Value;
    if qOsn.FieldByName('Discount').Value=True then GetCena
    else Cena1:=qOsn.FieldByName('Price').Value;

     Temp.FieldByName('Marka').AsString:=qOsn.FieldByName('Marka').Value;
     Temp.FieldByName('Osnovan').AsString:=qOsn.FieldByName('Name').Value;
     Temp.FieldByName('Litr').AsFloat:=qOsn.FieldByName('LitFact').Value;
     if qOsn.FieldByName('Report').Value=True then Temp.FieldByName('Summa').AsFloat:=qOsn.FieldByName('CurFact').Value
     else if qOsn.FieldByName('Report').Value=False then Temp.FieldByName('Summa').AsFloat:=0;

     Temp.FieldByName('Price').AsFloat:=qOsn.FieldByName('Price').Value;
     s:=(qOsn.FieldByName('LitFact').Value*Cena1)-qOsn.FieldByName('CurFact').Value;
     if s<0.4 then s:=0;
     Temp.FieldByName('Delta').AsVariant:=s;
     Temp.FieldByName('Report').AsBoolean:=qOsn.FieldByName('Report').Value;

     qOsn.Next;
    end;



    Так вот, при вызове вот этого:

    if qOsn.FieldByName('Discount').Value=True then GetCena



    Отчёт формируется минуты 2, а если опустить то мнгновенно.

    Для чего это нужно объясняю: формируется отчёт по потерям на скидках, скидка это

    s:=(qOsn.FieldByName('LitFact').Value*Cena1)-qOsn.FieldByName('CurFact').Value;



    Цену, по которой был продан ГСМ со скидкой выдернуть из таблицы нет возможности, т.к. там указана только текущая цена, а цены меняются постоянно.

    В самой таблице откуда дёргаются данные и переносятся в промежуточную таблицу

    Temp.FieldByName('Price').AsFloat:=qOsn.FieldByName('Price').Value;



    Так вот, чтобы получить розничную цену на момент продажи необходимо взять предыдущую, первую попавшую розничную цену. Но благодаря этому отчёт формируется минуты 2, а это не есть гут.

    Подскажите, как построить основной запрос, чтобы в нём дёргалась предыдущая, розничная цена, без всяких там моих извращений
  • Поросенок Винни-Пух © (28.11.08 10:00) [1]
    для начала сделайте цены как в хьюстоне. тогда потерь от скидок не будет.
    так как скидок не потребуется
  • Sergey13 © (28.11.08 10:16) [2]
    > [0] petvv   (28.11.08 09:25)

    > Так вот, при вызове вот этого:
    >
    > if qOsn.FieldByName('Discount').Value=True then GetCena
    >
    > Отчёт формируется минуты 2, а если опустить то мнгновенно.

    Значит запрос в GetCena работает медленно. Какие есть индексы на Statist?
    И почему частично ты используешь параметры, а частично подстановку?
  • Поросенок Винни-Пух © (28.11.08 10:25) [3]
    И почему частично ты используешь параметры, а частично подстановку?

    для парадокса это сильно повлияет на производительность?
    оно что его, запрепарит если параметры будут?
  • Sergey13 © (28.11.08 10:37) [4]
    > [3] Поросенок Винни-Пух ©   (28.11.08 10:25)
    > для парадокса это сильно повлияет на производительность?

    никак не повлияет, мне просто интересно.
  • Slym © (28.11.08 11:22) [5]
    petvv   (28.11.08 9:25)
    Cena.FindLast;
    Cena1:=Cena.FieldByName('Price').Value;

    ты уверен что FindLast это последняя цена? я нет! потому что не ORDER BY DateTime

    я бы сделал так

    //эту операцию выполнить 1 раз перед началом работы
    Cena.SQL.Add('select price from Statist where (Osnovanye=0) and (DateTime<:QDBeg) and (Product=:ProdID) ORDER BY DateTime DESC');
    Cena.Prepare;

    function TMainForm.GetCena(const Date:TDateTime;ProdID:integer;):variant;
    begin
    Cena.ParamByName('QDBeg').AsDateTime:=Date;
    Cena.ParamByName('ProdID').Value:=ProdID;
    Query1.Refresh;//непомню сработает или нет...
    if not Cena.isEmpty then
     result:=Cena.Fields[0].Value
    else
     result:=0;
    end;

  • Sergey13 © (28.11.08 11:36) [6]
    > [0] petvv   (28.11.08 09:25)
    > Так вот, чтобы получить розничную цену на момент продажи
    > необходимо взять предыдущую, первую попавшую розничную цену.

    Наверное надо брать цену на максимальную дату меньше заданой, а не "первую попавшую"?
  • Sergey13 © (28.11.08 11:53) [7]
    как вариант1
    перед расчетом выполнить запрос

    select s1.Product,s1.price
    from Statist s1
    where Statist.Osnovanye=0' and Statist.DateTime=
    (select max(DateTime) from Statist s2 where s1.Product=s2.Product s2.DateTime<:QDBeg)



    и в GetCena искать по нему locate по produkt.
    Желателен индекс по Product+DateTime

    вариант2
    подумать и попробовать добавить этот запрос (передланный конечно) к основному, для исключения временной таблицы вообще как класса.
  • petvv (30.11.08 20:28) [8]

    > вариант2подумать и попробовать добавить этот запрос (передланный
    > конечно) к основному, для исключения временной таблицы вообще
    > как класса.


    Вот этот вариант подходит больше. Завтра на работе попробую навоять запрос. А промежуточную таблицу использовал потому, что пришли с вопросом сегодня, а сделать надо было вчера вот и пришлось использовать таблицу, чтобы сделать вчера.
  • petvv (30.11.08 20:38) [9]

    > Наверное надо брать цену на максимальную дату меньше заданой,
    >  а не "первую попавшую"?


    Я имел в виду тоже самое, только выразил свою мыслю криво.
  • Loginov Dmitry © (01.12.08 22:15) [10]
    > Цену, по которой был продан ГСМ со скидкой выдернуть из
    > таблицы нет возможности, т.к. там указана только текущая
    > цена, а цены меняются постоянно.


    если "текущая цена" это НЕ тоже самое, что и "цена, по которой был продан ГСМ со скидкой", что тогда есть "текущая цена"?

    Вообще-то исходных данных маловато. Мы видим, что есть некая таблица "Statist", в которую входят как минимум 3 поля: price, DateTime, Product, Osnovanye.
    Также существует некая таблица, с которой осуществляется работа через набор данных "qOsn", включающая поля:
    Product, Osnovanye, Discount, DateTime, Price, Marka, Name, LitFact, CurFact, Report. Это одна и таже таблица, или разные? Судя по наименованиям Statist и qOsn - наверно разные. Тогда какое назначение у таблицы qOsn и у таблицы Statist? И почему "Цену, по которой был продан ГСМ со скидкой выдернуть из таблицы нет возможности", с чем связаны данные особенности проектирования БД?
 
Конференция "Базы" » Помогите оптимизировать запрос (D2007, BDE, Paradox) [Paradox]
Есть новые Нет новых   [134477   +39][b:0][p:0.003]