Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  MySQLi optimeerimine märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
mine lehele 1, 2  järgmine
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 02.09.2010 21:54:04 MySQLi optimeerimine vasta tsitaadiga

On 4 tabelit:
1) recipe_recipes (recipe_id, recipe_name, ...)
2) recipe_ingredients (ingredient_id, ingredient_price, ...) ingredient_price ehk hind on ühe ühiku kohta
3) recipe_ingredient_mapping (map_recipe, map_ingredient, map_quanitity)
4) recipe_related_recipes (related_parent, related_child, related_required)

Ühesõnaga on komponentide tabel, igal komponendil oma hind. Siis on retseptide tabel, igal retseptil nimi ja muud andmeid. Iga retsept koosneb kindlast arvust ja kindla kogusega komponentides. Igal retseptil võib olla seotud retsept, mis on kas nõutud (related_required = 1) või valikuline. Mul on vaja saada kõik retsepti andmed ning kogu retsepti hind.
Hind = SUM(iga retsepti komponendi hind * komponendi kogus) + SUM(iga seotud ja nõutud retsepti hind).
Ise tulin sellise lahendusega lagedale, aga äkki keegi oskab paremini:
sql:
  1. SELECT r.*, ROUND(SUM(m.map_quantity * i.ingredient_price), 2) AS hind
  2. FROM recipe_recipes r
  3.   JOIN (
  4.     SELECT recipe_id AS id, recipe_id AS osa FROM recipe_recipes
  5.     UNION
  6.     SELECT related_parent AS ID, related_child AS osa FROM recipe_related_recipes WHERE related_required = 1
  7.   ) AS s ON s.id =  r.recipe_id
  8.   JOIN recipe_ingredient_mapping m ON s.osa = m.map_recipe
  9.   JOIN recipe_ingredients i ON i.ingredient_id = m.map_ingredient
  10. WHERE r.recipe_id = 132
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 03.09.2010 13:32:49 Re: MySQLi optimeerimine vasta tsitaadiga

See päring on praegu kujul:

(ema + lapsed) X MuudHulgad

Saaks ilmselt ka nii teha päringu:

(ema X MuudHulgad) + (Lapsed X Muudhulgad)


Kui MySql-is on mingi võimalus päringute kiirusi võrrelda ("EXPLAIN PLAN" klausel vms), siis võiksid võrrelda nende variandi töökiirust.

Juhul kui sul alam/osa -retseptidel võib ka olla allüksusi, siis su päring neid ei arvesta. MySql-is pole vist veel tehtud "hierarhiliste päringute" funktsionaalsust (oracle CONNECT-BY klausel). mis võimaldaks puu-kujulisi andmeid läbida lõpmatu sügavuseni, seega tuleks MySql-is puukeste läbimiseks mingeid muid võtteid kasutada, aga seda siis ainult juhul kui sul saab alam-retseprilt olla omakorda alamaid.

Kas sinna päringusse "Group By" klauslit pole vaja lisada, kui päring väljastab veeru agregaat-funktsiooniga SUM?

Võiks proovida ka nii, et kas perfoomans muutub sellest kui "(ema + lapsed)" hulgakesse lisada filtrid sisse, ala nii:

(ema + lapsed, filtreeri) X MuudHulgad, filtreeri;
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 06.09.2010 14:47:02 vasta tsitaadiga

GROUP BY oli tõesti puudu.

MYSQLil on olemas EXPLAIN käsk, aga see midagi kasulikku (mulle) ei ütlenud, siis kasutasin kiiruse võrdlemiseks lihtsalt kogu tabeli küsimist ja vaatasin, kaua aega läheb.
(ema X MuudHulgad) + (Lapsed X Muudhulgad) oli tõesti kiirem, aga parima tulemuse sain hoopis alampäringuga:
sql:
  1. SELECT  r.*, (
  2.         SELECT ROUND(SUM(m.map_quantity * i.ingredient_price), 2)
  3.         FROM (
  4.                 SELECT recipe_id AS id, recipe_id AS osa FROM recipe_recipes
  5.                 UNION
  6.                 SELECT related_parent AS id, related_child AS osa FROM recipe_related_recipes WHERE related_required = 1
  7.           ) AS s
  8.           JOIN recipe_ingredient_mapping m ON s.osa = m.map_recipe
  9.           JOIN recipe_ingredients i ON i.ingredient_id = m.map_ingredient
  10.           WHERE s.id = r.recipe_id
  11. ) AS hind
  12. FROM recipe_recipes r


Alamretseptidel enam alamaid ei ole, sellega pole probleemi.

Tänud igatahes, teema minu poolt ammendatud.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 07.09.2010 21:32:01 vasta tsitaadiga

Mõned vead:

Kõige hullem asi mida sa SQLi kirjutades teha saad on kasutada funktsiooni andmete toomiseks või siis sinu puhul siis select selecti sees - see on kõige aeglasem ja baasi koormavam viis üldse.

Explain Plan on arendaja parem käsi, õpi selgeks! Ma ei kujuta ette, kuidas ilma selleta üldse normaalseid päringuid kirjutada võimalik on ...

Ei tea küll mis MySQLi versiooni kasutad, kuid minu teada on MySQLis juba kasutusel Oraclega sarnasd analüütilised funktsioonid ja juba üsna pikka aega - väga võimsad vahendid päringute muutmiseks tunduvalt kiiremaks, jällegi, vii kurssi ennast nendega.
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 07.09.2010 23:48:16 vasta tsitaadiga

serk kirjutas:
MySQLis juba kasutusel Oraclega sarnasd analüütilised funktsioonid ja juba üsna pikka aega


Keegi võiks üle googeldada selle väite, ja siia teada anda, võtaks teadmiseks ka ise. Ise googeldasin vaid hierarhiliste päringute tuge MySql-i kohta ja mäletan, et googli vastsed andsid mõista, et tugi puudub. Analüütiliste funktsioonide toe googeldamist pole veel jõudnud teha.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 08.09.2010 01:02:19 vasta tsitaadiga

MySQL versioon 5.1.36.
Uurisin natuke. Esimese postituse päring, kui kõik read küsida, (WHERE lõpust ära ja Group BY asemele) on 9 korda aeglasem kui minu järgmise postituse päring (phpMyAdmini näidatud aja põhjal). Põhjuseks oli "Copying to tmp table", millele kulus esimese päringu korral 90% ajast. Seega jääb õhku küsimus, et kas ikka on esimene päring parem (kui jah, siis miks)?

Mis puutub analüütilistesse funktsioonidesse, siis ma sain aru, et neid MySQLis ei ole, aga neid saab emuleerida. Samas ei näe, kuidas see peaks mind aitama.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 08.09.2010 10:38:25 vasta tsitaadiga

estrose kirjutas:
serk kirjutas:
MySQLis juba kasutusel Oraclega sarnasd analüütilised funktsioonid ja juba üsna pikka aega


Keegi võiks üle googeldada selle väite, ja siia teada anda, võtaks teadmiseks ka ise. Ise googeldasin vaid hierarhiliste päringute tuge MySql-i kohta ja mäletan, et googli vastsed andsid mõista, et tugi puudub. Analüütiliste funktsioonide toe googeldamist pole veel jõudnud teha.


--
Ongi ka Mysql'is olemas a-f-ide tugi:
http://onlamp.com/pub/a/mysql/2007/03/29/emulating-analytic-aka-ranking-functions-with-mysql.html?page=2
Enne OVER-klauslit kirjutatud funktsioon on analüütiline, ja andmebaasi mootoris on implementeeritud sedalaadi f-ioonide käitamine omat moodi, erinevamalt kui seda group-by-gaseotud agregaat funktsioonid töötavad. See erinev implementatsioon võib olla kiirem küll, võiks testida siis üle.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 13.09.2010 23:48:32 vasta tsitaadiga

Antud lehel peab jälgima, millal räägitakse MySQL-ist ja millal muust. MySQLil ei ole OVER-klauslit. Pealegi sain ma aru, et analüütilised funktsioonid on mõeldud selleks, et GROUP BY-d kasutades ei läheks infot kaduma. Mul seda probleemi pole.

Väike teemavahetus. Kui komponentide (ingredient) hinda muuta, siis peaksid vanad hinnad ka alles jääma. Tegin uue tabeli hinnad veergudega komponent, hind, kuupäev (tegelikkuses pole pealkirjad päris samad). Komponentide tabelisse jätsin hinna veeru alles. Kui kasutaja komponendi hinda muudab, siis lisan uue hinna hindade tabelisse kuupäevaga ja muudan komponentide tabelis ka. Aga kuidas käituda, kui kasutaja soovib mitut hinda korraga muuta. Kas lihtsalt iga komponendi korral 2 päringut (lisada uus hind hindade tabelisse ja muuta hind komponentide tabelis) või teha midagi, mis nõuaks vähem päringuid.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 14.09.2010 11:47:20 vasta tsitaadiga

Timukas0 kirjutas:
Aga kuidas käituda, kui kasutaja soovib mitut hinda korraga muuta. Kas lihtsalt iga komponendi korral 2 päringut (lisada uus hind hindade tabelisse ja muuta hind komponentide tabelis) või teha midagi, mis nõuaks vähem päringuid.


Sul on sisuliselt kaks tabelit: Toode (ID, Hind) ja Tooteajalugu (TooteID, Kuupäev, Hind). Mis selles muidu halba on, et kaks Salvestamist tehakse? See maha salvestamine Süsteemi ju ei koorma peaaegu üldse, aga andmete küsimine suurest ajaloo-tabelist on aeglane tegevus, sellepeale võiksid mõelda, kuidas selle tabeli poole pöördumist kiirendada. Ja andmebaasile mingeid trigereid ehk sündmusehaldureid ära lisa, tee ilma nendeta ikka.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 14.09.2010 12:24:01 vasta tsitaadiga

Ma just mõtlesin seda, kuidas PHPs andmebaasiga suhtlemine teha. Näiteks on kasutajal vaja 100 komponendi hinda muuta korraga. Kas teha php-ga kokku kokku 200 mysql_query-t (iga komponendi kohta 2), või siis näha vaeva ja vähendada vaja minevate päringute arvu.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 14.09.2010 12:51:38 vasta tsitaadiga

Mul tekkis see küsimus, et kui juba sellist lahendust kasutatakse, kas siis ei oleks mõistlik hindade tabelisse tekitada veerud id, hind, kehtivuse_lopp ja komponentide tabelisse mitte hinda numbriliselt salvestada, vaid viidata kehtivale hinnale id kaudu? Andmete dubleerimine kahte tabelisse ei tundu hea mõte olevat andmebaasi disaini mõttes.
_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 14.09.2010 14:29:24 vasta tsitaadiga

MySql-is näib olema võimalik andmebaasi protseduure teha:
http://dev.mysql.com/tech-resources/articles/mysql-storedprocedures.html

siis sul võiks ju olla selline üks andmebaasi protseduur, mida välja kutsud:

protseduur SalvestaToode:
   Salvesta Toode.
   Salvesta TooteAjalugu.


Võib-olla oleks tõesti parem nii teha, et teed andmebaasi protseduuri, mis võtabki sisendiks ühe korraga kõik 100 asja, ei tea kas see oleks võimalik.

Toote põhiatribuudid ongi Hind ja Nimi, need peaks kindlasti asuma Toote tabelis. Andmete dubleerimine, agregeerimine üle andmebaasi on perfoomansi suhtes hea valik. Peamine näide on tuntud relatsioon ArvePäis ja ArveRead, kus tabelist ArveRead summeeritakse kokku ridade Summa ja salvestatakse tabelisse ArvePäis, veergu Summa, see on pea igas infosüsteemis nii, et agregeeritakse ja dubleeritakse, eesmärgiga, et hiljem kergem oleks andmed kätte saada. Kuid ma pole kunagi reaalselt näinud andmete dubleerimist turva-eesmärkidel. Ala, et panna isiku parool kahte tabelisse vms. OLen aga seda näinud ühe programmeerija proovitöös, kui ta kandideeris palgatööle.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 14.09.2010 20:47:47 vasta tsitaadiga

Võtsin kasutaja Fukiku ideest kinni. Tabelil hinnad nüüd neli veergu: id (auto increment), komponendi_id, hind, kuupäev (current timestamp) ja komponentide tabelis on veerus `hind` vastava hinna id. Paljude komponentide muutmisele pakuks siis sellise lahenduse: php-ga teen umbes sellise päringu (kuupäev t:
sql:
  1. INSERT INTO hinnad (komponent, hind) VALUES (1, 10), (2, 7), ...

Ja siis "kopeerin" hindade tabelist viimati lisatud komponentide id-d komponentide tabelisse:
sql:
  1. UPDATE hinnad AS h1
  2. LEFT JOIN hinnad AS h2 ON (h1.komponent = h2.komponent AND h1.kuupäev < h2.kuupäev)
  3. LEFT JOIN komponendid k ON  h1.komponent = k.id
  4. SET k.hind = h1.id 
  5. WHERE h2.komponent IS NULL
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 14.09.2010 22:05:00 vasta tsitaadiga

Ma päeval vastasin umbropsu ja lühidalt. Seega, mis halvasti, see uuesti icon_smile.gif

Ühesõnaga, mina jätaks su hindade tabeli nii, nagu ma enne soovitasin (id, komponent_id, hind, kuupäev) ja komponentide tabelisse viidet hinnale üldse ei panekski.

Siis esiteks oleks hinna lisamine lihtsam, piisaks ainult insert lausest hindade tabelisse (komponent_id väärtust sa ju lisamisel tead, muud aga pole vaja).

Hinna pärimiseks sobiks midagi taolist:
sql:
  1. SELECT h.* FROM hinnad AS h WHERE h.komponent_id = ? AND h.kuupaev = MAX(h.kuupaev)

NB! ei garanteeri päringu 100% töötavust, sest pole ühtegi mängubaasi hetkel võtta, kus katsetada.

Kokkuvõttes aga kõik lihtne ja elegantne ja ei pea tegema sellist keemiat, nagu sa eelmises postituses pakkusid, mille funktsioneerimises ma siiamaani päris kindel pole icon_smile.gif

_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 15.09.2010 11:45:28 vasta tsitaadiga

Tere,
Hiljem saab olema sellise lahendusega andmebaas aeglane.
Ajaloo tabel saab olema Süsteemi kõige aeglasem tabel, ja seda peaksite tee siis kogu aeg join-idesse lisama. Lisaks jääb veel arusaamatuks, kuidas andmebaasilt vastust saada, millise rea salvestamine andmebaasi vea andis.
MySql-is polegi kollektsioone vist, tuleb komaliste koostada stringide näol, kui on kollektsioonide vajadus. Ma soovitaks teha andmebaasi protseduuri, mis kollektsiooni sisendiks võtaks, ja väljastaks, missugune rida vea andis. Arvan, et see protseduur oleks kiire ja hiljem toote jooksva hinna pärimine oleks ka normaalne.


---

Võib-olla siiski ei tulegi aeglane lahendus, mida pakute siin! Andke siis kunagi utlevikus teada, kas perfoomants on okei! MySql-is saab ka partitsioneerida tabeleid, seda võiks ajaloo tabeli jaoks uurida.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 17.09.2010 23:10:05 vasta tsitaadiga

Fukiku, sinu kood kahjuks ei tööta. Toimiks kas selline:
sql:
  1. SELECT h1.* FROM retsept_hinnad h1 WHERE h1.kuup = (SELECT MAX(h2.kuup) FROM retsept_hinnad h2 WHERE h2.komponent = h1.komponent)

või see:
sql:
  1. SELECT h1.* FROM retsept_hinnad AS h1
  2. LEFT JOIN retsept_hinnad AS h2 ON (h1.komponent = h2.komponent AND h1.kuup < h2.kuup)
  3. WHERE h2.komponent IS NULL

Mõlemad võrdlemisi aeglased (primary key'd ei saa ka kasutada). Seega kasutaks kas hinna dubleerimist või primary key-ga JOINimist.
Lugesin nüüd läbi ühe varasem estrose postituse, mis enne kuidagi kahe silma vahele jäi ja hetkel eelistan hinda kahes tabelis hoida.

Veel tekkis küsimus, et kui oluline on vaja teada, milline rida täpselt vea andis? Muidu teeks lihtsalt nii, et kui päring ei õnnestu, siis nii ütlengi kasutajale. Pole ise sellist asja kohanud (samas pole ka suuri kogemusi), et kui kasutada näiteks mu eelmise postituse INSERT INTO päringut, siis osad andmed sisestatakse ja osad mitte.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 19.09.2010 21:00:16 vasta tsitaadiga

Hinnaveeru selline dubleerimine on lühidalt öeldes "kiire aga hallatamatu" lahendus. Hallatamatu on ta selles osas et tuleb hallata, et dubleeritud andmed oleksid süngis, aga seda on raske tagada. Kiire on see lahendus, kuna tegu on eelarvutusega. Andmebaasi indeksid on eelarvutuslik ja dubleeriv nähtus, mis saamuti tekitab ohu, et see süngist välja läheb, kuid me ei pea indekseid kuigi palju ise haldama, andmebaasimootor teeb seda ise, indeks on korras kogu aeg. Kuid dubleeritud Hinnaveerge süngis hoida on raske, varem või hiljem miski juhtub ja ongi üks kahest väärtusest erinev. Niiet "kiire aga raskelt hallatav" asi on üldiselt see dubleerimine. Sedalaadi dubleerimise lahenduse juurde tuleks ilmselt alles siis tulla, kui kõik muud variandid on ära proovitud, ja tõepoolest perfoomansit muul traditsioonilisemal viisil parandada ei saa. Samas minuarust selline dubleerimise häkk tundub teoorias huvitavana, võiks proovida praktiliselt.

Kui mul oleks veebileht, kus oleks 100 tekstikasi, siis võiks ju öelda, millises tekstikastis on vale väärtus, kus ma ise neist 100 kastist selle vale üles oskaks leida.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 19.09.2010 22:36:09 vasta tsitaadiga

Põhimõtteliselt ma ei dubleeri hinna veergu. Komponentide tabelis on hetke hind ja hindade ajaloo tabelis on hindade ajalugu. See, et mingi komponendi ajaloo tabeli viimane kirje kattub kattub hetke hinnaga on kokkusattumus :d. Jätab võimaluse kasutada ka selliseid hindu, mida pole vaja või ei tohiks ajaloo tabelisse salvestada (kuigi hetkel sellist funktsionaalsust vaja ei lähe).

tsitaat:
Kui mul oleks veebileht, kus oleks 100 tekstikasi, siis võiks ju öelda, millises tekstikastis on vale väärtus, kus ma ise neist 100 kastist selle vale üles oskaks leida.

Enne kontrollin PHP-ga need 100 kasti ikka üle. Kui mõni ei sobi, annan kasutajale teada. Alles siis käivitan päringu.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 20.09.2010 13:38:00 vasta tsitaadiga

Toote käesoleva hinna jaoks võiks sobida selline päring:
sql:
  1. SELECT * FROM hinnad
  2. WHERE HindKuni IS NULL  AND TooteID=&&ID;
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Timukas0
HV kasutaja
Timukas0

liitunud: 20.03.2007



Autoriseeritud ID-kaardiga
sõnum 20.09.2010 15:15:46 vasta tsitaadiga

Hindade ajaloo tabeli struktuur on selline
sql:
  1. CREATE TABLE IF NOT EXISTS `retsept_hinnad` (
  2.   `komponent` int(11) NOT NULL,
  3.   `hind` float NOT NULL,
  4.   `kuup` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
  5. )

Kuna hetkel puudub vajadus kasutajal ise aega määrata (à la eelmine kuu sel ajal oli selline hind), siis läheb lihtsalt hinna lisamise aeg andmebaasi.

Üldiselt olen tänu sellele teemale tunduvalt targemaks saanud. Edasi saan juba oma jõududega hakkama. Tänud aitajatele.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 27.09.2010 15:20:15 vasta tsitaadiga

Foorumid ongi hea koht, kus saab programmeerimist õppida. Teine hea koht on töökoht, kus on hea mentor-töökaaslane, kellega lahenduste üle arutada, kuid sellist kaas-töötajat paljudes töökohtades ei leia.

--

Lisaks mõned aspektid andmete dubleerimise kohta, mida aastakümnetega välja kujunenud hea tava heaks ei kiida, aga mida siiski tehakse järgmiste põhjustega:

1. Kui juhtub olukord, et tabeli T üle ei taheta anda isikule S õigusi andmeid küsida, siis on üheks lahenduseks dubleerida andmeid andmebaasis, tuua/dubleerida veerg sinna tabelisse kuhu on ligipääs olemas.
2. Andmete küsimise operatsiooni perfoomansi tõstmine. Jääb ära kulukas join.
3. Andmebaasi tasemel andmete turvalisuse tagamine. Häkker ei saa muuta parooli-veergu niilihtsalt, kuna andmebaas takistab seda öeldes et see veerg on sõltuv ühest teisest dubleeritud veerust, referential integriti vms kaitseks andmemuudatust.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 28.09.2010 19:04:39 vasta tsitaadiga

estrose kirjutas:

1. Kui juhtub olukord, et tabeli T üle ei taheta anda isikule S õigusi andmeid küsida, siis on üheks lahenduseks dubleerida andmeid andmebaasis, tuua/dubleerida veerg sinna tabelisse kuhu on ligipääs olemas.

Andmeid ei lubata teatud tabelitest pärida kindlatel põhjustel. Pigem tuleks siinkohal selgeks saada põhjus, miks vastav operatsioon on näiteks dba või riskide poolt keelatud. Andmete dubleerimine on väga väga bad practice töö tabelites - tekivad kohe küsimused, et mis andmed on primaarsed, kuidas neid süngis hoida, kuidsa käituda migreerimisel, kui vaja ühest tabelist andmed kustutada jne ... lõputud jamad, mis teevad kokkuvõttes elu põrguks arendajal kes seda krdi kompotti hiljem sööma peab.

estrose kirjutas:

2. Andmete küsimise operatsiooni perfoomansi tõstmine. Jääb ära kulukas join.

Aga paneme siis kõik andmed ühte tabelisse? Oracle võimaldab sul 1000 veergu panna. Peaks ju nagu piisama? Dubleerime kõik, kliendid, aadressid, arved jne ... Kui JOIN tekitab sinu andmemudelis probleeme, siis on sul midagi seal väga valesti või lihtsalt ei osata päringut kirjutada - sagedasem põhjus ...

estrose kirjutas:

3. Andmebaasi tasemel andmete turvalisuse tagamine. Häkker ei saa muuta parooli-veergu niilihtsalt, kuna andmebaas takistab seda öeldes et see veerg on sõltuv ühest teisest dubleeritud veerust, referential integriti vms kaitseks andmemuudatust.

icon_eek.gif
Kui häkkeril on otsene ligipääs sinu tabelitele, siis mida enam sa seal kaitsed? Umbes sama loogiline, kui et topime igale võimaliku kohale foreign key'd peale põhjendusega, et äkki häkker ei suuda siis delete lauseid kasutada... Kui soovimatu isik saab ligipääsu baasile, siis on anyway pees ...
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 28.09.2010 20:31:49 vasta tsitaadiga

Ja veel ka neljas põhjus:

4. Andmebaasi peale ehitatud tarkvara on piirangutega, mis teeb dubleerimise ainuvõimalikuks lahenduseks.

Seega 4 juba, üritan veel siia tuua neid.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 28.09.2010 21:26:22 vasta tsitaadiga

estrose kirjutas:
Ja veel ka neljas põhjus:

4. Andmebaasi peale ehitatud tarkvara on piirangutega, mis teeb dubleerimise ainuvõimalikuks lahenduseks.

Seega 4 juba, üritan veel siia tuua neid.
Siis on üldjuhul ikkagi probleemiks kehv arhitektuuriga tarkvara ja/või kehv andmemudel - andmete dubleerimist õigustada infosüsteemi suutmatusega on ka nagu naljakas. Minumeelest peaks iga tõsiselt võetava infosüsteemi andmemudel olema A ja O, mille järgi ehitatakse rakendus, mitte vastupidi.
_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
Le Inc
HV Guru
Le Inc

liitunud: 06.09.2002



Autoriseeritud ID-kaardiga
sõnum 04.10.2010 13:57:12 vasta tsitaadiga

Pole küll MySQL aga Oracle (sarnased icon_biggrin.gif).

Miks peale oracle service restarti suurest tabelist lugemise kiirus (select * from) langeb ~11 sekilt ~2 sekile? See on muidugi tore, aga küss selles miks ta päeva jooksul jälle 11 sekile maandub? Kas asi on mingites indeksites vms? Kuidas saaks asja "jäädavaks" teha. Ehk mõni spets teab.
Kommentaarid: 56 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 54
tagasi üles
vaata kasutaja infot saada privaatsõnum
nemu
HV vaatleja
nemu

liitunud: 22.01.2002



Autoriseeritud ID-kaardiga
sõnum 04.10.2010 15:49:43 vasta tsitaadiga

Buffer cache saab muud jura täis?
Võid cache hinti proovida:
select /*+ CACHE(table_name) */ * from table_name
Kommentaarid: 12 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 11
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 04.10.2010 16:09:04 vasta tsitaadiga

Le Inc kirjutas:
Pole küll MySQL aga Oracle (sarnased icon_biggrin.gif).

Miks peale oracle service restarti suurest tabelist lugemise kiirus (select * from) langeb ~11 sekilt ~2 sekile? See on muidugi tore, aga küss selles miks ta päeva jooksul jälle 11 sekile maandub? Kas asi on mingites indeksites vms? Kuidas saaks asja "jäädavaks" teha. Ehk mõni spets teab.


Küsimus millele baasi nägemata suhteliselt võimatu vastata.

Aga üldiselt näen kahte võimalust:
1) Päring loetakse mälust
2) Kogu tabel tõmmatu mällu ja tänu sellele kiire fetch.

Mis vahendiga sa päringuid teed? Kas fetchid alati kõik read või ainult top rows? Kas peale restarti esimene päring, full fetch, toimub 2 sekiga ja teine 11 sekiga, või käib esimene kord kauem ja teine siis välgukiirusel, kas WHERE tingimus muutub päringutes? Kirjelda rohkem olukorda.
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 04.10.2010 16:19:05 vasta tsitaadiga

serk,
kui suuri süsteeme oled teinud? Niikaua, kui ülesandeks on Kalle Kusta pagaritöökoja 10 kuklit kolmele hulgimüüjale müüa, on kõik ilus ja lihtne. Ükspäev aga satud ülesande otsa, kus tabelites on miljoneid kirjeid ja klient ootab süsteemilt regeerimist sekundi jooksul. Siis võid ennast halliks optimeerida aga denormaliseerimisest ei pääse.

"ligipääs baasile" - on päris erineval tasemel ja meetodil ligipääsu võimaldamist. Üldjuhul välistele pooltele kuvatakse andmeid läbi view - selle definitsiooni saab muuta jooksvalt vastavalt vajadusele ilma, et teine pool peaks andmemudeli muudatuste tõttu andmevahetust muutma hakkama (lisaks on õiguste probleem sellega lihtsalt lahendatav). Kui teisel poolel on vaja andmeid lisada, siis selleks tehakse eraldi tabel või protseduur. Jällegi selleks, et väljast tulevad andmed oleksid võimalikult eraldatud muust andmemudelist ja liides ei sõltuks andmemudeli muudatustest. Ma olen näinud ka lahendust, kus sisuliselt kogu salvestus baasi käis läbi protseduuride (ma ei ütle, et see mõistlik oleks aga ka nii saab ja seal oli isegi vaieldav põhjus).

Le Inc,
Oracle (ja ka muud "suured" serverid) optimeerivad oma tööd jooksvalt. Üks päring võib seetõttu tõesti võtta erinevalt aega sõltuvalt sellest, millise plaani alusel server selle lahendab. Nii umbes 8 aastat tagasi olin ise tunnistajaks, kus Oracle baas vajas iga paari nädala tagant sunniviisilist statistika ümberarvutamist, sest suutis ennast jooksvalt "lolliks optimeerida". Mis siis lahendus oli, ei mäleta kahjuks.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 04.10.2010 16:28:13 vasta tsitaadiga

2korda2 kirjutas:
serk,
kui suuri süsteeme oled teinud? Niikaua, kui ülesandeks on Kalle Kusta pagaritöökoja 10 kuklit kolmele hulgimüüjale müüa, on kõik ilus ja lihtne. Ükspäev aga satud ülesande otsa, kus tabelites on miljoneid kirjeid ja klient ootab süsteemilt regeerimist sekundi jooksul. Siis võid ennast halliks optimeerida aga denormaliseerimisest ei pääse.

"ligipääs baasile" - on päris erineval tasemel ja meetodil ligipääsu võimaldamist. Üldjuhul välistele pooltele kuvatakse andmeid läbi view - selle definitsiooni saab muuta jooksvalt vastavalt vajadusele ilma, et teine pool peaks andmemudeli muudatuste tõttu andmevahetust muutma hakkama (lisaks on õiguste probleem sellega lihtsalt lahendatav). Kui teisel poolel on vaja andmeid lisada, siis selleks tehakse eraldi tabel või protseduur. Jällegi selleks, et väljast tulevad andmed oleksid võimalikult eraldatud muust andmemudelist ja liides ei sõltuks andmemudeli muudatustest. Ma olen näinud ka lahendust, kus sisuliselt kogu salvestus baasi käis läbi protseduuride (ma ei ütle, et see mõistlik oleks aga ka nii saab ja seal oli isegi vaieldav põhjus).

Le Inc,
Oracle (ja ka muud "suured" serverid) optimeerivad oma tööd jooksvalt. Üks päring võib seetõttu tõesti võtta erinevalt aega sõltuvalt sellest, millise plaani alusel server selle lahendab. Nii umbes 8 aastat tagasi olin ise tunnistajaks, kus Oracle baas vajas iga paari nädala tagant sunniviisilist statistika ümberarvutamist, sest suutis ennast jooksvalt "lolliks optimeerida". Mis siis lahendus oli, ei mäleta kahjuks.


Täiesti arusaamatu postitus. Aga vastus sinu küsimusele: väga suuri, hetkel suurim tabel millega töötan ca 50 miljonit kirjet.
Jah, Oracle ise optimeeribki oma käivitusplaane vastavalt statistikale. 8a tagasi oli Oracle midagi muud kui ta praegu on... Seletad ehk mida sa ikkagi öelda tahtsid?
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 04.10.2010 16:31:38 vasta tsitaadiga

Kui aru ei saanud, ju pole piisavalt keerulisi süsteeme teinud. Väide, et andmete dubleerimine on IGAL JUHUL paha ei päde lihtsalt.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 04.10.2010 16:38:40 vasta tsitaadiga

2korda2 kirjutas:
Kui aru ei saanud, ju pole piisavalt keerulisi süsteeme teinud. Väide, et andmete dubleerimine on IGAL JUHUL paha ei päde lihtsalt.


Selge, nüüd sain topicust ka aru ja saan sulle vastata.

Kui me räägime mat. viewdest ja viewdest, siis sinna andmete tekitamine ja perioodiline refresh ei ole andmete dubleerimine andmemudeli mõistes, see on täiesti erinev asi. Väga paha on töötabelites andmete dubleerimine, see on asi millest rääkisime ja mida kellelegi ei soovitaks.
Ka endal jooksevad peamised ja suured aruanded mat viewdel, sest töötabelitest päringu tegemine käiks mitmeid tunde.

Ma ei saa aru miks HinnaVaatluses osad inimesed nii agressiivsed on ... icon_smile.gif

Cache hint üldjuhul aitab väga hästi, kui sa teed järjestikuselt full scanne samale tabelile, kuna aga sinu täpset probleemi siiski ei tea, siis proovida ju võib, aga kui ei funka, pane kirja täpsemalt ja detailsemalt - saame siis aidata.
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 04.10.2010 17:12:45 vasta tsitaadiga

EI! Ma ei pidanud silmas mat. viewsid vaid justnimelt andmemudeli denormaliseerimist! Küsimus ei ole aruandes - küsimus on töökuvade kiires toimimises. Kui suur aruanne sekundiga ei avane, siis see üldjuhul kedagi ei morjenda, kui aga tavaline töökuva 2 sekundit avaneb, siis on kasutaja õigustatult kuri. Kui korraga on kuval andmeid 5-7 tabelist ja igaühes on miljoneid kirjeid, siis kasulikum on paar veergu dubleerida ja saada tabelite hulk <=3 peale.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 04.10.2010 20:57:43 vasta tsitaadiga

Olgu, teeme rahu, kuna me ei tea üksteise tööstussektoreid, siis vaielda raske, ühele sobib üks, teisele teine.
Aga arvestades sellega, et käesolevas foorumis, ka käesolev topic, tehakse üldjuhul tavalisi veebilahendusi, siis nendel juhtudel ei küündi nende andmemaht eales tasemeni, mil tuleks hakata denormaliseerima icon_smile.gif

Aga nagu ennist öeldud, denormaliseerimist mina isiklikult ei poolda ja väldiks igal võimalikul viisil, kuna see tekitab siiski probleeme:
1) Andmete up-to-date hoidmine
2) Lisa kettaruum
3) Andmemudeli lisa keerukus ja insert, update, delete aeglustumine(FK;PM;Constraindid)
4) Arenduskulu tunduvalt kallim, nii baasi kui UI seisukohast.

Andmete kuvamise kiirus on tegelt lõputu probleem ning lähenemisviise on erinevaid, kes soovitab osta kõvemat rauda, kes süsteemi ümber kirjutada jne ... Ainuõiget teed polegi.

Aga oli tore vaielda icon_smile.gif Edu.
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
Le Inc
HV Guru
Le Inc

liitunud: 06.09.2002



Autoriseeritud ID-kaardiga
sõnum 05.10.2010 08:23:04 vasta tsitaadiga

serk kirjutas:
Mis vahendiga sa päringuid teed? Kas fetchid alati kõik read või ainult top rows? Kas peale restarti esimene päring, full fetch, toimub 2 sekiga ja teine 11 sekiga, või käib esimene kord kauem ja teine siis välgukiirusel, kas WHERE tingimus muutub päringutes? Kirjelda rohkem olukorda.

Oli tabel ca. 650 000 kirjega, keskmine select käis ~15 sekki (veebilehele, mis kuvas esimesed 15 rida. Mul on stopper php's peale pandud). Tegin tabeli kaheks, jätsin uude tabelisse 1 kuu andmed (otseselt pole juurdepääsu kasutajal vaja, käiks tegelt ka paaripäevane ajalugu), nüüd käib sama päring 11 sekki. Seda on ikkagi palju.

Suurt listi vaatame sisevõrgust, seda kasutaja nii või naa ei näe, aga sisse logimisel kasutatakse sama tabelit kõige värskemate andmete näitamiseks. Sealt tuleb ka pikk laadimise aeg. Võimalik et saaks kuidagi kuupäevaga vms vahendiga Oracle "täistabelit" mitte pärima.

Lühidalt öeldes on ehk nippe kuidas asja optimeerida ... ?

Raud on ka kehva, 5a. vana server. Järgmine aasta hangiks SSD raid'i siis ehk hakkaks looma.

PS! Vastused su küsimustele:

- Mis vahendiga sa päringuid teed? Kas fetchid alati kõik read või ainult top rows?
Select ikka pärin? palju on ka in klausleid, see ka annab palju juurde

- Kas peale restarti esimene päring, full fetch, toimub 2 sekiga ja teine 11 sekiga, või käib esimene kord kauem ja teine siis välgukiirusel, kas WHERE tingimus muutub päringutes? Kirjelda rohkem olukorda.
Peale restarti esimene täis päring (175 000 rida) käis 5,3 sekki, teine juba 1,7 sekki ja nii jääbki mõneks tunniks, siis jälle 11 seki peal. Peale restarti need veebilehe päringud mis võtavad ~3,5 sekki tehakse 1 sekiga (kaks select in jms. alampäringuid).


viimati muutis Le Inc 05.10.2010 08:39:06, muudetud 1 kord
Kommentaarid: 56 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 54
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 05.10.2010 08:35:43 vasta tsitaadiga

Plaan vaja üle vaadata. Kas päring kasutab indekseid või laseb full scan? Kui indekseid ei kasuta, siis muuda kas päringut või lisa indeks, kuhu vaja. Kui group by vms sees pole, siis 4 sekundit sellise hulga juures on hiiglama palju (tingimusel, et sa ei lae üles mingit suurt "pildiinfot" vms).
Veel 1 asi mida kindlasti tähele panna - tarkvaraliselt (ehk päringuid optimeerides, mudelit kohendades) võid teinekord võita kiiruses tuhandeid kordi, riistvara annab ka väga heal juhul tubli suurusjärgu võrra vähem tagasi. Samas riistvara on tihtipeale odavam ja seetõttu ka lihtsama vastupanu tee icon_smile.gif Mul on endal jälle kogemus, kus üks üsna suur protseduur töötas esimeses "ah peaasi et töötab" versioonis ca 30 minutit. Pärast kahte päeva optimeerimist sai selle alla 20 sekundi peale. Seejuures andmemudelit ei muudetud (kui mitte arvestada protseduuri töö käigus juurde tekkinud ajutisi tabeleid). Riistvaraliselt poleks sellise tulemuseni lihtsalt jõudnud.

serk,
sry, ma olen hellaks tehtud igasugu "hiilgavate" lahendustega ja seetõttu kipun järsult reageerima. Mõte on ikkagi selles, et andmete dubleerimine suurte süsteemide korral on paratamatus. Jah, on kallim arendada ja hallata aga kui alternatiiviks on tatina veniv rakendus, siis lihtsalt pole muud võimalust. Samas tõsi ta on - siit foorumist abi otsiv tegelane tõenäoliselt sellist süsteemi ei tee. Peace!
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 05.10.2010 12:06:49 vasta tsitaadiga

Hei

Esimene full scan käib sul 5.3 sekki, järgmine päring mis sul käib 1.7 sekki käib mälust. Paari tunni pärast on mälust päring minema lükatud ja tehakse järjekordselt full scan.
Tuunimise aitamiseks oleks hea kui saaksid postitada create tabel scriptid koos veergude kommentidega - data võin ise insertida. Ning peamine, päring mis seal peal käib - on vaja äriliseslt aru saada mida tahetakse näidata. Peale seda saab mõelda kuidas seda kõike tuunida. Explain plan ei teeks samuti paha.

Aga nagu eelmine postitaja ütles, siis tõenäoliselt korrektsed indeksid aitaks.

Näiteks:
1) Teha ta mat. view'ks kuhu esmalt täitagi ainult need 15 rida mida tahad näidata ning edaspidi kasutada fast refreshi
2) Indekseerida tabel
3) Tõmmatagi tabel jõuga mällu
4) jne ... väga palju erinevaid võimalusi

Aga ennem kui postitad tableite struktuure või datat, ole kindel et sa võid seda teha!
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
kiiver
HV vaatleja

liitunud: 03.04.2003




sõnum 05.10.2010 13:13:05 vasta tsitaadiga

Le Inc kirjutas:
Tegin tabeli kaheks, jätsin uude tabelisse 1 kuu andmed (otseselt pole juurdepääsu kasutajal vaja, käiks tegelt ka paaripäevane ajalugu), nüüd käib sama päring 11 sekki. Seda on ikkagi palju.

Suurt listi vaatame sisevõrgust, seda kasutaja nii või naa ei näe, aga sisse logimisel kasutatakse sama tabelit kõige värskemate andmete näitamiseks. Sealt tuleb ka pikk laadimise aeg. Võimalik et saaks kuidagi kuupäevaga vms vahendiga Oracle "täistabelit" mitte pärima.


Ilma andmestruktuuri ja päringuta on raske midagi soovitada aga eelneva kirjelduse järgi jääb küll mulje, et indekseid pole üldse kasutusel. 650k reaga tabeli poolitamine kuupäeva järgi ei näi kuidagi õigustatud kuna üks indeks kuupäeva peale ja päringus näiteks tingimus KUUPAEV > trunc(sysdate)-30 ja rownum <= 15 peaks andma esimesed 15 rida 30 päeva seast hetkeliselt (alla 10 ms).
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
Le Inc
HV Guru
Le Inc

liitunud: 06.09.2002



Autoriseeritud ID-kaardiga
sõnum 05.10.2010 13:45:36 vasta tsitaadiga

Nõus. Indekseid pole, nüüd tegin. Võtsin ID (unikaalne nr igas reas) indeksi aluseks. Ilmselt on mul jah sql päring optimeerimata. Proovin ümber kõpitseda .. asi sai tehtud kunagi ammu, kui veel sql suurt midagi ei jaganud. icon_biggrin.gif

Kahjuks vist veebilehe põhised ~3 sekised vist jäävad. Seal on väga palju mitme tabeli vahelist suhtlemist, aga ehk annab midagi teha.
Kommentaarid: 56 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 54
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 05.10.2010 13:58:37 vasta tsitaadiga

Le Inc kirjutas:
Nõus. Indekseid pole, nüüd tegin. Võtsin ID (unikaalne nr igas reas) indeksi aluseks. Ilmselt on mul jah sql päring optimeerimata. Proovin ümber kõpitseda .. asi sai tehtud kunagi ammu, kui veel sql suurt midagi ei jaganud. icon_biggrin.gif

Kahjuks vist veebilehe põhised ~3 sekised vist jäävad. Seal on väga palju mitme tabeli vahelist suhtlemist, aga ehk annab midagi teha.
Targemad nüüd parandavad mind kohe, aga minu primitiivne pea ütleb, et ID peale indeksi tegemine on hea, sest tõenäoliselt selle järgi päritakse asju tihti. Lisaks peaksid vaatama oma päringud üle ja tegema indeksid ka muudele veergudele, mida kasutad päringutes WHERE osas. Hetkel, kui sul on indeks ID peale, kuid pärid mingi kuupäeva järgi, siis on sellest indeksist selle päringu kiirendamiseks null kasu.

Eksperdid nüüd materdagu ja täpsustagu, kui ma midagi väga ämbrisse panin.

_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
mirko28
Aeg maha 1p
mirko28

liitunud: 31.12.2003




sõnum 05.10.2010 14:10:30 vasta tsitaadiga

tsitaat:
Targemad... primitiivne pea...materdagu ..ämbrisse


See materdamise ajastu on ammu läbi juba. Interneti suhtluskultuur on teismelise-east juba välja kasvanud selle mõne aastaga, mil internet laildasemalt kättesaadav on olnud. Keegi ei hakka siin materdama, pole vaja karta, ega ise seda teha.

Vaatan, et päris palju huvitavaid lisakommentaare on siia teemasse tulnud, rõõm näha, loen.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
Le Inc
HV Guru
Le Inc

liitunud: 06.09.2002



Autoriseeritud ID-kaardiga
sõnum 05.10.2010 14:52:54 vasta tsitaadiga

Indexitega ID luges 650k rida kokku 0,57 sekki, ilma index'iteta 2,1 sekki. Töötab. icon_biggrin.gif
Kommentaarid: 56 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 54
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 12:44:29 vasta tsitaadiga

Fukiku,
tabelis veerg ID peaks oma olemuselt olema PK ja seega automaatselt indekseeritud. Ilma PK-ta tabel on saadanast, nagu siin ühes teises teemas sai nenditud.
Aasta oli siis umbes 2002, kui huvi pärast sai testitud indekseerimata Sybase IQ baasi: 4M kirjega tabelist "group by" jms koledate tingimusega 100 rida tuli ~12 sekundiga (serveriks tavaline tolle aja lauaarvuti). Korralikult indekseeritult tavalised mootorid (Oracle, Sybase ASE) suutsid sama päringu läbi teha ca 5 sekundiga. Koos indeksitega oli IQ kordi kiirem aga need hinnad.... $15000 ainult ühe protsessoriga serveri litsentsi eest (kasutajad tulid veel juurde) oli vähestele tollal jõukohane. Kui tuli veel selgitada, et see ei ole mitte töökeskkonna vaid ainult andmelao jaoks, siis... Praeguseks peaks Eesti pinnal olema päris mitu IQ kasutajat (Elisa ja SEB tulevad nagu meelde).
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 12:53:01 vasta tsitaadiga

2korda2 kirjutas:
Fukiku,
tabelis veerg ID peaks oma olemuselt olema PK ja seega automaatselt indekseeritud. Ilma PK-ta tabel on saadanast, nagu siin ühes teises teemas sai nenditud.
Aasta oli siis umbes 2002, kui huvi pärast sai testitud indekseerimata Sybase IQ baasi: 4M kirjega tabelist "group by" jms koledate tingimusega 100 rida tuli ~12 sekundiga (serveriks tavaline tolle aja lauaarvuti). Korralikult indekseeritult tavalised mootorid (Oracle, Sybase ASE) suutsid sama päringu läbi teha ca 5 sekundiga. Koos indeksitega oli IQ kordi kiirem aga need hinnad.... $15000 ainult ühe protsessoriga serveri litsentsi eest (kasutajad tulid veel juurde) oli vähestele tollal jõukohane. Kui tuli veel selgitada, et see ei ole mitte töökeskkonna vaid ainult andmelao jaoks, siis... Praeguseks peaks Eesti pinnal olema päris mitu IQ kasutajat (Elisa ja SEB tulevad nagu meelde).
Seda ma mõistan, et PK on automaatselt indekseeritud ja ilma PK'ta tabel on saatanast. Kas mul aga selles osas oli õigus eelmises postituses, et indeksid peaksid olema tehtud ka neile veergudele, mille järgi tabelist andmeid päritakse? Indekseeritud PK ei aita meid ju, kui me mingi suvalise tekstilise veeru järgi reaalselt päringu teeme - ilma indeksita toimub ju vist sel juhul ikkagi full scan?
_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 13:15:22 vasta tsitaadiga

Jah, said õigesti aru. Päringus peab üldiselt kasutama indekseeritud veergu(sid). Samas kui mul on näiteks isikute tabel ja ma tahan kõiki meessoost isikuid, siis veerg SUGU, mis omab väärtusi M,N ei ole hea indekseerida - ei anna suurt midagi juurde. Üldiselt on mõtet indekseerida veergusid, kus on piisavalt palju erinevaid väärtusi ja ühtlasi selle veeru väärtusi kasutatakse päringute tegemisel. Kuupäev on tüüpiline näide.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
Le Inc
HV Guru
Le Inc

liitunud: 06.09.2002



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 15:44:41 vasta tsitaadiga

Tundus et minu puhul oli kala tabelis endas. Nimelt 650k veeruga tabelist tegin lahjema 170k veeruga tabeli (enne kopeerimine, siis delete), aga lugemise kiirus langes paarkümmend %. Tegin uue tabeli vana põhjal ja kopeerisin info 1:1 üle. Nüüd loeb ~5..6x kiiremini. Ka veebileht on 3..4x kiirem.

Ilmselt oli oracle tabeli suurema hulga peale ära optimeerinud, seega ei tulnud ka 4x andmete vähendamine erilist kiiruse võitu. Muide hetkel ei oli ühtegi indeksit, töötab kenasti.
Kommentaarid: 56 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 54
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 06.10.2010 16:57:54 vasta tsitaadiga

Indeks on efektiivne siis kui sa pärid vastavalt indeksile suhteliselt väikest osa tabeli andmetest - ei mäleta peast enam seda rule of thumb % määra.
Üldiselt oleks tark peale indeksi loomist vaadata päring uuesti explain planiga üle.

Sinu tabeli probleemi kohta:
Oracle soovitab uuesti statistika arvutada kui 10% andmetest muutub ja kui selle peale query pange paneb. Defauldis peaks Oracle iga 24h tagant seda anyway ise tegema - võin siin muidugi hetkel eksida, pean järgi vaatama manualist.
Mälu järgi oli käsk selleks: DBMS_STATS.gather_table_stats -viitsimist on siis, proovi.

See 10% on muidugi "pseudo" väärtus ja pole kuldne reegel, kõik sõltub paljudest muudest teguritest. Mõnikord võib isegi väiksem data change käivitusplaani jumala metsa keerata ja vastupidi... Muudad, testid, muudad, testid, muudad, testid .... ja toodangus võib ikka asi pekkis olla icon_biggrin.gif
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
nemu
HV vaatleja
nemu

liitunud: 22.01.2002



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 20:53:07 vasta tsitaadiga

DBMS_STATS.gather_table_stats "deprecated", kuid lihtsamini meeles püsiv alternatiiv on:
ANALYZE TABLE <table_name> <COMPUTE | DELETE | ESTIMATE> STATISTICS;

Väikeste tabelite jaoks siis compute (kogu andmete pealt), suurtele estimate.
* Statsita tabelite testimiseks võib kasutada DYNAMIC_SAMPLING hinti.
* Tabeli statistika saab lukku lükata kui andmete muutmine päringuplaanid sassi ajab.
* 11g versioonis peaks olema virtuaalsed indeksid, mida reaalselt valmis ei tehta, aga päringuplaani muutusi saab testida.
Kommentaarid: 12 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 11
tagasi üles
vaata kasutaja infot saada privaatsõnum
serk
HV kasutaja

liitunud: 24.05.2003




sõnum 06.10.2010 22:28:25 vasta tsitaadiga

nemu kirjutas:
DBMS_STATS.gather_table_stats "deprecated", kuid lihtsamini meeles püsiv alternatiiv on:
ANALYZE TABLE <table_name> <COMPUTE | DELETE | ESTIMATE> STATISTICS;



Ei saa küll nõustuda sinu poolse vastusega - hardly keegi enam analyze'i tänapäeval kasutab, võibolla kiireteks testideks ainult - analyze käib kiiremini. CBO jaoks on dbms_stats alati olnud parem valik, sellekohta ka palju detailset infot väljas miks see just nii on.

11.1:
Compute Statistics
Deprecated: Use DBMS_STATS

Note: Do not use the COMPUTE and ESTIMATE clauses of ANALYZE to collect optimizer statistics. These clauses are supported for backward compatibility. Instead, use the DBMS_STATS package, which lets you collect statistics in parallel, collect global statistics for partitioned objects, and fine tune your statistics collection in other ways. The cost-based optimizer, which depends upon statistics, will eventually use only statistics that have been collected by DBMS_STATS.


viimati muutis serk 06.10.2010 22:44:01, muudetud 2 korda
Kommentaarid: 8 loe/lisa Kasutajad arvavad:  :: 1 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
nemu
HV vaatleja
nemu

liitunud: 22.01.2002



Autoriseeritud ID-kaardiga
sõnum 06.10.2010 22:41:13 vasta tsitaadiga

Kogu eelmine postitus viitab ju kiirele testile kui segaseks jäi.
Kommentaarid: 12 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 11
tagasi üles
vaata kasutaja infot saada privaatsõnum
morgoth
HV kasutaja
morgoth

liitunud: 14.01.2004




sõnum 08.10.2010 17:46:00 vasta tsitaadiga

2korda2 kirjutas:
Fukiku,
tabelis veerg ID peaks oma olemuselt olema PK ja seega automaatselt indekseeritud. Ilma PK-ta tabel on saadanast, nagu siin ühes teises teemas sai nenditud.
Aasta oli siis umbes 2002, kui huvi pärast sai testitud indekseerimata Sybase IQ baasi: 4M kirjega tabelist "group by" jms koledate tingimusega 100 rida tuli ~12 sekundiga (serveriks tavaline tolle aja lauaarvuti). Korralikult indekseeritult tavalised mootorid (Oracle, Sybase ASE) suutsid sama päringu läbi teha ca 5 sekundiga. Koos indeksitega oli IQ kordi kiirem aga need hinnad.... $15000 ainult ühe protsessoriga serveri litsentsi eest (kasutajad tulid veel juurde) oli vähestele tollal jõukohane. Kui tuli veel selgitada, et see ei ole mitte töökeskkonna vaid ainult andmelao jaoks, siis... Praeguseks peaks Eesti pinnal olema päris mitu IQ kasutajat (Elisa ja SEB tulevad nagu meelde).


Tabelil ei pea ju ilmtingimata mingit autoincrement PK välja olema... Näiteks, kui tegemist on miski seoste tabeliga.
Kommentaarid: 11 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 10
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  MySQLi optimeerimine mine lehele 1, 2  järgmine
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.