Autor Téma: Parametrizované príkazy  (Přečteno 5185 krát)

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2054
  • Karma: 91
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Parametrizované príkazy
« Odpověď #15 kdy: 20-12-2017, 14:36:57 »
Pokud potrebuji soupat moc dat, tak pouzivam StoredProc.
Embarcadero MVP - Czech republic

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #16 kdy: 20-12-2017, 14:48:01 »
S parametrami vs bez parametrov - porovnanie rýchlosti:
FireBird EMBEDDED (najnovsia verzia)
V 5 000 cykloch sa pomocou SELECT vyhľadáva 7 slov v rámci tabuľky o 221 riadkoch
(original bol 50 000 cyklov - viac podrobnosti k testom v citacii na zaver)
FireBird s pouzitim parametrov:  854 ms
FireBird bez parametrov    : 7 448 ms
Rozdiel v čase takmer 10 - nasobok.
Kód: Delphi [Vybrat]
  1. // Vyhľadávanie s parametrom - znížený počet cyklov na 5000, pôvodne 50000
  2.   dm.qry.Params.Clear;
  3.   dm.qry.SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ?';
  4.   dm.qry.Params[ 0 ].DataType := ftString;
  5.   dm.qry.Params[ 0 ].IsCaseSensitive := true;
  6.   dm.qry.Prepare;
  7.   dm.qry.Active := true;
  8.   k      := 0;
  9.   with dm.qry do
  10.     for i := 1 to 5000 do
  11.       begin
  12.       Params[ 0 ].AsString := 'oxymoron';
  13.       Refresh;
  14.       if not eof then
  15.         Inc( k );
  16.       Params[ 0 ].AsString := 'query';
  17.       Refresh;
  18.       if not eof then
  19.         Inc( k );
  20. ..
Kód: Delphi [Vybrat]
  1. // Vyhľadávanie bez parametrov
  2.   stw.Start;
  3.   k      := 0;
  4.   with dm.qry do
  5.     for i := 1 to 5000 do
  6.       begin
  7.       SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ''oxymoron''';
  8.       Active := true;
  9.       if not eof then
  10.         Inc( k );
  11.       SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ''query''';
  12.       Active := true;
  13.       if not eof then
  14.         Inc( k );
  15. ..
Presne takéto vyhľadávania boli skúmané aj pre Dictionary, StringList, HashedStringList, SQLite a SQLite in-Memory.
Na úplný záver je v príspevku prehľadná tabuľka výsledkov.
"Benchmark: Dictionary vs StringList vs HashedStringList vs SQLite in Memory" Link:

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3520
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Parametrizované príkazy
« Odpověď #17 kdy: 20-12-2017, 16:12:09 »
Citace
A porad to nejak nevim. Ty chces sestavit model z Delphi trid a vygenerovat pro nej schema databaze a vsechny potrebne dotazy? Nebo obracene? Nebo jakou mas predstavu?
Výraz "schéma databázy" mi nič nehovorí, okrem toho, že existuje ;)
Jednoducho mám kopu MyQuery.SQL.Text := SameString (INSERT INTO, UPDATE, DELETE A SELECT). A bolo by dobré v tom urobiť poriadok.
  • vylúčiť opakované veci
  • čo sa dá automatizovať, tak automatizovať. Viď príspevok od raul
  • dostať to von z formulárov
Priam so železnou pravidelnosťou sa mi pre rôzne typy SQL opakuje, čo sa dá určite nejako optimalizovať (skryť):
Kód: [Vybrat]
  Fqry_I.ParamByName('FKFOCS').AsInteger := oGlobalVar.IDFOC;  // Vždy pracujem len s jedným domom
  Fqry_I.ParamByName('YEARS').AsInteger := oGlobalVar.CurrentYear;  // a jedným rokom
Posledný Radkov príspevok mi toho dosť objasňuje.

Poznámka: neviem čo si mám predstaviť pod výrazom "entity framework".

PS: dovolím si poznámku k Radkovej ukážke. Bolo by dobré zbaviť sa niekoľko násobného použitia SQL.Add, lebo každé priradenie vyvolá v pozadí overovanie textu. Viď "// prima cast". Jednoznačne tu odporúčali SQL.Text :=
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #18 kdy: 20-12-2017, 16:23:25 »
Citace
PS: dovolím si poznámku k Radkovej ukážke. Bolo by dobré zbaviť sa niekoľko násobného použitia SQL.Add, lebo každé priradenie vyvolá v pozadí overovanie textu. Viď "// prima cast". Jednoznačne tu odporúčali SQL.Text :=
No niekedy je pridavanie nutne. Nie som si isty, keby si pridaval cez string ci to bude ovela rychlejsie
Kód: Delphi [Vybrat]
  1. if s= '' then
  2.   s:= 'nejaky text'
  3. else
  4.   s= s + #13#10 + 'nejaky text'
  5. qry.SQL.Text:=..
myslim, ze keby si pridal takto, malo by to na rychlost snad stacit.
Kód: Delphi [Vybrat]
  1. qry.SQL.BeginUpdate;
  2. qry.SQL.Add
  3. ..
  4. qry.SQL.EndUpdate;
  5.  
teda ak uz priamo to Add malo len zdrzovat

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3520
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Parametrizované príkazy
« Odpověď #19 kdy: 20-12-2017, 16:25:46 »
Už som si ten "entity framework" vyhľadal. Nič pre mňa.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #20 kdy: 20-12-2017, 16:31:15 »
Tak v prvom rade ak by sa dalo
Kód: HTML [Vybrat]
  1. .ParamByName( .. ).AsInteger
nahradit pomocou:
Kód: HTML [Vybrat]
  1. .Params[ .. ].AsInteger
Citace
Kód: [Vybrat]
  Fqry_I.ParamByName('FKFOCS').AsInteger := oGlobalVar.IDFOC;  // Vždy pracujem len s jedným domom
  Fqry_I.ParamByName('YEARS').AsInteger := oGlobalVar.CurrentYear;  // a jedným rokom
Posledný Radkov príspevok mi toho dosť objasňuje.

Veril by som, ze ked sa ti to opakuje, tak by sa dal vyspekulovat nejaky rozumny cyklus, ktory by ti ubral rutinnu pracu..
« Poslední změna: 20-12-2017, 16:34:16 od mibainfo »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #21 kdy: 20-12-2017, 16:37:53 »
myslim, ze keby si pridal takto, malo by to na rychlost snad stacit.
Kód: Delphi [Vybrat]
  1. qry.SQL.BeginUpdate;
  2. qry.SQL.Add
  3. ..
  4. qry.SQL.EndUpdate;
  5.  
Takto by to slo, ale .Add opakovane pro nekolik radku bez uzamceni stringlistu je vylozene skodlive, protoze to po pridani kazdeho radku vola SQL parser, ktery samozreme na neuplnem SQL prikazu havaruje...

Je otazka, proc delat Begin/EndUpdate, kdyz muzu rovnou napsat Text := a ten text si pred tim slozit v nejakem StringBuilderu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #22 kdy: 20-12-2017, 16:41:16 »
Tak v prvom rade ak by sa dalo
Kód: HTML [Vybrat]
  1. .ParamByName( .. ).AsInteger
nahradit pomocou:
Kód: HTML [Vybrat]
  1. .Params[ .. ].AsInteger
Tak to bych silne nedoporucoval, urcite ne jako premature optimization, protoze si tim zhorsi udrzovatelnost kodu, protoze pri kazdem pridani cehokoli bude miset neustale zkoumat poradi parametru. K tomu bych se uchylil jedine, kdyz je to funkci, odladene a je treba to optimalizovat, jinak je to nebezpecna technika.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #23 kdy: 20-12-2017, 16:45:20 »
Priam so železnou pravidelnosťou sa mi pre rôzne typy SQL opakuje, čo sa dá určite nejako optimalizovať (skryť):
Kód: [Vybrat]
  Fqry_I.ParamByName('FKFOCS').AsInteger := oGlobalVar.IDFOC;  // Vždy pracujem len s jedným domom
  Fqry_I.ParamByName('YEARS').AsInteger := oGlobalVar.CurrentYear;  // a jedným rokom
Posledný Radkov príspevok mi toho dosť objasňuje.
[/code]
Je celkem normalni, ze kdyz clovek pracuje s DataSety, tak si postupne nadela celou sadu pomocnych funkci kterou vice ci mene postupne zobecnuje, takze prece neni zadny problem tohle vzit, dat do samotne subroutiny a tu nekde vhodne volat.


Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #24 kdy: 20-12-2017, 16:46:32 »
Už som si ten "entity framework" vyhľadal. Nič pre mňa.
Ani nič pre Delphistu ;-)

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #25 kdy: 20-12-2017, 16:52:32 »
Tak v prvom rade ak by sa dalo
Kód: HTML [Vybrat]
  1. .ParamByName( .. ).AsInteger
nahradit pomocou:
Kód: HTML [Vybrat]
  1. .Params[ .. ].AsInteger
Tak to bych silne nedoporucoval, urcite ne jako premature optimization, protoze si tim zhorsi udrzovatelnost kodu, protoze pri kazdem pridani cehokoli bude miset neustale zkoumat poradi parametru. K tomu bych se uchylil jedine, kdyz je to funkci, odladene a je treba to optimalizovat, jinak je to nebezpecna technika.
A co takto miesto ciselneho indexu pouzit enum, kde si mozes nadefinovat polozku lubovolneho znenia. A mozes to pouzivat v cykloch? (Na rozdiel od stringu..) Samozrejme tiez v mnozinovych operaciach.
Pripadny prevod enum, resp. set na Byte, Integer, Int64 je okamzity (tam aj spat).
Proste pohodlie a prehlad a ucinnost dohromady? Teda ak uz mam nieco oprimalizovat a automatizovat vo velkom?
« Poslední změna: 20-12-2017, 16:56:34 od mibainfo »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #26 kdy: 20-12-2017, 16:59:16 »
Poor
Rated 1 time
A co takto miesto ciselneho indexu pouzit enum, kde si mozes nadefinovat polozku lubovolneho znenia. A mozes to pouzivat v cykloch? Samozrejme tiez v mnozinovych operaciach.
Pripadny prevod enum, resp. set na Byte, Integer, Int64 je okamzity (tam aj spat).
Proste pohodlie a prehlad a ucinnost dohromady? Teda ak uz mam nieco oprimalizovat a automatizovat vo velkom?
Co je na tom za pohodli pri zmene poradi parametru v SQL at uz pridanim nebo ubranim parametru  rucne prepisovat nekde enumy?

Ty ses tem optimalizacema nejakej posedlej... vetsinou nez to stacis vsechno zmerit, napsat otestovat (a v neposledni rade nastudovat), tak vyrobce zrychli HW 2x ;)


Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #27 kdy: 20-12-2017, 17:39:06 »
OK,
  • automatizacia a optimalizacia  :(
  • uz pred XXL rokmi sa mi prestalo pacit kompilovanie databazoveho programu, pretoze skoro kazdu hodinu prisli nove poziadavky.
  • lepsie ked staci SQL a netreba nic kompilovat v Delphi ci C#. Samozrejme bezne by to nestacilo. Ale automatizacia.. Nie vzdy, ale mnohokrat to ide
  • samozrejme pri zmene struktury je vzdy problem. Lenze pri zmene struktury toho treba aj tak kopu opravovat, ci nie?
  • nepracujem s velkymi databazovymi systemami, ktore by bolo treba casto menit, preto sa moj pohlad moze lisit.
« Poslední změna: 20-12-2017, 18:01:57 od mibainfo »

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 376
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Parametrizované príkazy
« Odpověď #28 kdy: 20-12-2017, 17:59:08 »
Takto by to slo, ale .Add opakovane pro nekolik radku bez uzamceni stringlistu je vylozene skodlive, protoze to po pridani kazdeho radku vola SQL parser, ktery samozreme na neuplnem SQL prikazu havaruje...
Da sa chapat, ze aj ked plati:
Kód: Delphi [Vybrat]
  1. Query.Active=False
neuplny SQL kod sa cez to vsetko kontroluje na vykonatelnost? To som nevedel.
« Poslední změna: 20-12-2017, 18:03:31 od mibainfo »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2271
  • Karma: 123
    • Verze Delphi: D2007, XE3, DX10
Re:Parametrizované príkazy
« Odpověď #29 kdy: 20-12-2017, 18:31:12 »
Da sa chapat, ze aj ked plati:
Kód: Delphi [Vybrat]
  1. Query.Active=False
neuplny SQL kod sa cez to vsetko kontroluje na vykonatelnost? To som nevedel.
Nemusi to mit obecnou platnost tj. je to treba zkoumat pro konkretni komponenty, ale vetsinou jako SQL pouzivali TWideStringList a tomu nastaivil OnChange event. A ten string list nemel zadne povedomi, o nejakem Query.Active, proste kdyz se mu zmenil obsah, tak event odpalil...

Je treba se podivat na obsluhu te udalosti v QueryChanged u konkretni komponenty, ale vetsinou vede naopak ke shozeni Active na FALSE a pak dela neco takoveho:
Kód: Delphi [Vybrat]
  1. procedure TSQLQuery.QueryChanged(Sender: TObject);
  2. begin
  3.   if not (csReading in ComponentState) then
  4.   begin
  5.     Close;
  6.     SetPrepared(False);
  7.     if ParamCheck or (csDesigning in ComponentState) then
  8.     begin
  9.       FCommandText := SQL.Text;
  10.       FText := FCommandText;
  11.       SetParamsFromSQL(nil, False);
  12.     end
  13.     else
  14.       FText := SQL.Text;
  15. {$IF DEFINED(CLR)}
  16.     DataEvent(dePropertyChange, nil);
  17. {$ELSE}
  18.     DataEvent(dePropertyChange, 0);
  19. {$IFEND}
  20.   end
  21.   else
  22.     FText := FParams.ParseSQL(SQL.Text, False);
  23.   SetFCommandText(FText);
  24. end;
  25.  

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: