Jump to content
php.lv forumi

SELECT * vienreiz vai SELECT vairākas reizes atsevišķi tikai vajadzīg


404

Recommended Posts

Ir skripts,kurš tiek pārrakstīts maz ko no oģināla atstājot,tāpēc ir izdevība pēc vajadzības izmainīt problemātiskāko.

Tā kā nav pieredzes ar noslogotām datubāzēm,tad interesē kāds variants būtu ieteicamāks manā gadījumā,optimizējot dažas lietas(vai arī atsakoties no domas).Skripts nav tas žiglākais,tāpēc,cik nu iespējams tiek šis tas pamainīts.

Pašlaik katrreiz izsaucot jebkuru failu,notiek vairākas pieslēgšanās users tabulai.Katreiz tiek izvilkts info tikai no dažiem laukiem no ~50 tabulā esošajiem.Sākumā tiek izvilkts autorizācijai vajadzīgais(4 lauki),tad kverijs liegumu čekošanai(7),vēl viens kverijs include failā,kas izvelk usera settingus(6),un visbeidzot pārējais pēc vajadzības,atkarībā no faila.Vidēji index lapā katrreiz vēl ir ap 20 kverijiem uz citām tabulām.(Useru skaits bāzē ap 1200).Tā kā kveriju jau tā ir pietiekoši,tad ir doma ka varētu taisīt vienreiz pilno * selektu sākumā,liekot iekš array pilnīgi visu usera info,un tālāk izmantot tikai masīvu.Jautājums ir-cik liela ir laika atšķirība,vai tiek taisīts * un ielasīti vēl masīvā visi 50 lauki,no kuriem labi ja puse tiek izmantota,vai notiek daži atsevišķi selekti,katrs tikai vajadzīgos dažus ierakstus.Katrs konekts tak it arī prasa laiku.Tas būs ātrāk nekā * visu ielasīt,vai tomēr nē? Kurš variants būtu ātrāks un ar mazāku slodzi bāzei? Pie lielāka online useru skaita būs būtiska atšķirība starp abiem variantiem? Pakomentējiet,kam nav slinkums,kā paši organizējat šādus variantus :)

Edited by 404
Link to comment
Share on other sites

nu SELECt * pats par sevi nav labakais , tomer peec iespejas izmantot SELECT lauks, lauks2, lauks _n Tas nu taa ..

Bet Jatceras ka VIslielaaka Bremze ir konektejoties pie DB .

1. parbaudiit vai netiek vairakas reizes veikta konekteesanas

2. Ja vien iespejams Kveriju skaitu samazinaat

Ne tikai SELECT visi_lauki_kas_buus_vajadziig Bet japaskataas vai nevar kaadu tabulu uzreiz piesaistii Ar JOIN (parasti ja ir tik daudz kveriju tad ir liela varbuutiba ka var gan )

 

3. jaskatas kas tie par datiem , varbuut ir verts Optimizeet pashu datu struktuuru

Paskatiities vai teiksim kautkur netiek izmantota stringa meklesana, kur lieliski varetu iztikt ar TinyInt

Ir redzets tada lieta ka meklee saliidzina peec Yes No (datu tips Warchar 255 ) kur krietni efektiivak buutu SET (pat neparakstot pashu PHP dalju )

shadas niences nedaudz, bet tomer bremzee visu lietu (nedaudz ja useru skaits ir neliels)

4. pareizi !!! Noindekseet DB

Nemakuliigi izmantoti Indeksi Labakajaa gadijumaa neko nemainiis Sliktakajaa Uzliks lieku slodzi ...

 

5. Paskatiities vai netiek ielasiiti lieki dati

teiksim kautkaads masiivs kas Varbuut tiks izmantots , ja Useris kautko rakstiis DB , Taa kaa Lasiisana/Rakstiisana parasti ir VISMAZ 3/1 tad uz sham ir verts pieverst uzmaniibu

---

Link to comment
Share on other sites

Ir tikai viena pilnīgi droša atbilde uz Taviem jautājumiem un pieņēmumiem par to kas strādā ātrāk - TESTS. Un sāc ar to, kas aizņem visvairāk laiku.

Pieņemot, ka Tev ir MySQL (ak KĀPĒC KĀPĒC tik daudz ļaužu šo informāciju slēpj :O), tad vēl dažas citas idejas papildus Grey_Wolf teiktajam specifiski par MySQL ir atrodamas šeit un norādēs no šī raksta un dažas citas vairāk par Oracle savukārt šeit.

Gribētu minēt vismaz pirmos divus, kas ir ļoti universāla jebkurai DBVS:

1. Iespēja kaut ko izdarīt visātrāk ir to nedarīt vispār, tāpēc par katru SQL teikumu būtu jāpārliecinās:

- vai tas vispār ir vajadzīgs, varbūt to var nemaz nepildīt,

- vai to tiešām ir nepieciešams pildīt tik daudz reižu (ciklā), varbūt to var pildīt tikai vienreiz (piemēram iegūt kodu no db, aizpildīt mainīgo ar sistēmas datumu utml),

- varbūt to var pildīt tikai kādos speciālos gadījumos (if, case).

2. Pēc iespējas jādomā kopas operācijās. Jāmēģina izvairīties no procedurālas SQL teikumu sasaistes. Ja problēmu ir iespējams atrisināt tikai ar SQL līdzekļiem, tad vispārējā gadījumā tā arī jādara. Jo sevišķi jāmēģina izvairīties no SQL konstrukcijām, kas ir ievietotas PL/SQL (PHP, Python, Java, C whatever kas cits) ciklos.

 

Gints Plivna

http://datubazes.wordpress.com

Edited by Gints Plivna
Link to comment
Share on other sites

Būs ko pastudēt.Jā-bāze ir MySQL,un konektēšanās notiek tikai vienreiz.Faktiski pēc users datiem pārējie gandrīz visi ir SELECT COUNT(*) kveriji,kas ar šķiet diezgan iebremzē pasākumu,jo skaitāmā ir daudz.Tiek izvadīts viss,saistībā ar saita statistiku un jaunumiem-tēmas forumā,aptauju skaits,balsojumi,draugi onlainā,vēstuļu skaits,interešu klubi u.t.t. Varētu no tā atteikties,atstājot tikai linkus bez cipariņiem pie viņiem(lapa ir uz mobilajām ierīcēm orientēta),bet tad galvenā lapa zaudē lielu daļu informatīvās nozīmes par notiekošo saitā. Ciklu gan nekādu nav,bet ir pāris vietas ar include failiem,kuri vēl satur funkcijas ar dažiem SELECT kverijiem.To JOIN galvenajā gan nesanāks izmantot,bet user profilā-tur izskatās,ka būs tieši tas kas vajadzīgs :) String vērtību laukos ir maz,jo user settingus cenšos visur kur var,kā INT() definēt,un pēc viņa attiecīgi lasīt nozīmi.Paeksperimentēšu vēl,kas strādās raitāk,bet tad pagaidām laikam jāpaliek pie tā,ka * tomēr netaisīt,un lai ņem dažus ierakstus atsevišķos īsos kverijos,nekā visu blāķi lasīt masīvā. Paldies par info un linkiem.Pie pāris jaunām idejām nonācu :)

Link to comment
Share on other sites

piemeemeeram useru setingus var glabaat cepumaa ....

tad tos sanaaks ielasiit vienu reizi ...

kad useris logojas tad sho kveriju var apvienot ar lieguma paarbaudes kveriju.

palasi shito: http://lv.php.net/microtime

 

vari pameeriit cik ilgaa izpildas kursh koda bloks un tad meklee taalaaku risinaajumu tam kas izpildas ilgi ...

Link to comment
Share on other sites

SELECT COUNT(*) kveriji,kas ar šķiet diezgan iebremzē pasākumu,

Vispar ja skaita no vienas tabulas tad var izmantot

SELECT count(lauks_1), COUNT(lauks_2) FROM tabulis WHERE xx=yy AND zzz='bla_bla' GROUP BY lauks_x

COUNT(*) atieciiba pret COUNT(lauks) Mysql ir Optimizeets taa kaa parak shamam bremzeet nevajadzeetu ...

Link to comment
Share on other sites

Tā kā tām skaitāmajām vērtībām ir tikai informatīva nozīme,un nekur citur viņas izmantotas vairs netiek,tad radās vēl viena doma,ka varbūt nemaz COUNT katrreiz netaisīt,bet visas vērtības glabāt kā stringu mazā txt failiņā jau saskaitītas,un nolasīt no tā.Un tikai,ja kaut kas izmainās,tad vienlaicīgi ar bāzes update,pārrakstīt viņu.Tad tiktu vaļā no nepārtrauktās visa iespējamā saskaitīšanas.Par to settingu glabāšanu iekš COOKIES doma iepatikās-noteikti kaut ko no tā pārnesīšu uz cepumiem vai sesiju.Ģenerācijas laiks jau skriptā ir-tad manīs,cik kas būs efektīgi :)

Link to comment
Share on other sites

Tā kā tām skaitāmajām vērtībām ir tikai informatīva nozīme,un nekur citur viņas izmantotas vairs netiek,tad radās vēl viena doma,ka varbūt nemaz COUNT katrreiz netaisīt,bet visas vērtības glabāt kā stringu mazā txt failiņā jau saskaitītas,un nolasīt no tā.Un tikai,ja kaut kas izmainās,tad vienlaicīgi ar bāzes update,pārrakstīt viņu.Tad tiktu vaļā no nepārtrauktās visa iespējamā saskaitīšanas.

Hmmm varu tikai atbalstīt...

Tā kā neesmu MySQL specs, tad varbūt kaut ko salaidīšu dēlī, tāpēc lūdzu pārējiem koriģēt, ja kas.

Patiesībā MySQL šai ziņā pieradina izstrādātājus un lietotājus pie specifiskām īpašībām, kas citās DBVS nav t.i. cik man zināms MyISAM tabulas vienkārši skaita ierakstus (vai kaut kā tā) un count(*) from table būs momentāns. Tas ir iespējams tāpēc, ka inserti tiek serializēti (zem Concurrency). Piemēram Oracle un SQL Serverī tā nebūs, jo reāli vairāki lietotāji vienlaicīgi var likt iekšā tabulā datus un lai noskaidrotu skaitu būs jālasa cauri vismaz vismazākais indekss, kas satur NOT NULL kolonas (parasti primary key indekss). Tas tā neliela atkāpe, kāpēc MySQL lietotāji pēkšņi ir pārsteigti, ka citās DBVS count(*) nav nemaz tik lēts un ātrs. Starp citu arī neMYISAM tabulām šķiet, ka šis ātrums nebūs.

Šeit arī var palasīties par citām MySQL count(*) īpašibām.

Kas attiecas uz pašu konceptu par count(*), tad 99% gadījumu tā ir fīča kas ir apmēram līmenī nice to have, bet nebūt nav būtiska sistēmas funkcionēšanai (must have), piemēram, kaut vai šai pašā forumā - vai kādam ir absolūti būtiski zināt precīzu skaitu, cik katrs tēma reizes ir lasīta? Skaits var būt aptuvens, to patiesībā var nerādīt vispār un var arī teiksim atjaunot reizi stundā, nevis kalkulēt katru reizi no jauna. Es turos pie domas, ka jebkurš count(*) faktiski ir atskaite un tām jau ir pavisam citas prasības ātrdarbībai salīdzinot ar normālu ievadformu attēlošanu.

Un runājot par glabāšanu failā - var arī glabāt DB, tikai uzlikt kādu procesu, kas periodiski atjauno skaitu(-s) vienreiz stundā/dienā/mēnesī pēc vajadzības.

 

Gints Plivna

http://datubazes.wordpress.com

Link to comment
Share on other sites

1)Pirmkārt, MySQL count(*) ir ātrs tikai uz MyISAM. Savukārt, InnoDB, kas rullē uz tabulām, kur daudz raksta datus, count(*) ir lēnāks.

2)Visas statistikas var kešot, pārrēķināt racionālā laika periodā (crontabs vai arī skripts pie lapas, kas nočeko keša valīdumu un pie vajadzības pārrēķina),

3)JOINi, index`i utt.

Link to comment
Share on other sites

Idejiski cik esmu petijis tad Mysql Count(*) skaita tiiri ierakstus neskatoties Uz vai ir NULL vai nav Count(lauks) gan skataas vai veriiba nav NUUL ..

--

Piekritiishu Gintam ka count() vajag izmantot pec iespejas mazaak, bet nu ir gadijumi kad bez vinja apieties ir gruuti ... teiksim saskaitiit komentarus rakstam .. kur vertiiba var mainiities sameraa strauji, tur gan parasti nav parak gigantiski datu apjomi un reti ierakstu daudzums sazniez simtos K nerunajot jau par M ..

---

404 --> varbuut tas userim izvadamaas vertiibas ir verts glabaat atseviskjaa tabulaa?? un kad tiek kas mainiits tad pamaina arii vertiibu , VAi kaa jau tika minets laiku pa laikam veic updeitu ...

+ teiksim taadu lietu kaa Jaunaas vestules (mesages) nebuut nav izdeviigi parbaudiit ar Count() , labak ir saglabat DB tabulaa un tiko atnak jauna taa vienkarshi Updeito to tabulas ierakstu ... --> liidzko Useris skatas taas vestules taa attieciigi visu Nonnulee ....

---

Link to comment
Share on other sites

Idejiski cik esmu petijis tad Mysql Count(*) skaita tiiri ierakstus neskatoties Uz vai ir NULL vai nav Count(lauks) gan skataas vai veriiba nav NUUL ..

 

count(izteiksme) skaita tos un tikai tos ierakstus kur izteiksme atgriež rezultātu NOT NULL.

Attiecīgi count(*) vienmēr būs NOT NULL priekš jebkura ieraksta, tieši tāpat kā count(1) vai count('mana_super_konstante').

Savukārt izmantojot count(<kolona>), protams, ka izteiksme <kolona> dod null, ja kolonas vērtība ierakstam ir null. Tātad tas netiek pieskaitīts.

Tieši tas pats attiecas uz visām pārējām grupēšanas funkcijām. Svarīgi ir tas, ko atgriež izteiksme iekš grupēšanas f-jas.

 

Gints Plivna

http://datubazes.wordpress.com

Link to comment
Share on other sites

Nonācu pie vairākiem jauniem risinājumiem un paldies par padomiem. :) Tas MySQL perfomances blogs ar interesantu vielu pārdomām dod.

Wolf,tā arī darīšu,ka būs 1 keštabula,kura apdeidojas tikai kaut ko no tā info izmainot(piemēram pievienojot jaunu foruma tēmu).Glabājamā būs pietiekoši,un tur ar sākotnēji domāto stringu iekš txtfaila tiešām netikšu cauri.Tāpat ar laiku nāks klāt citas fīčas,un par īsu būs.

Link to comment
Share on other sites

ar sākotnēji domāto stringu iekš txtfaila tiešām netikšu cauri.

Nu bet text.failaa glabaat info ir krietni neizdeviigag nekaa DB tas jau tapat bija skaidrs, jo pat glabajot tikai 1 vertiibu, pie 1K useriem naksies parsijat pilniigi visus ierakstus, VAI nu njemt peec faila rindu Numuriem (skaitiit pec /n /t ??? ) un ljoti ceret ka kartiiba ir saglabata... + tapat glabat DB ierakstu kura rinda nu buus jalasa ..

---

Tapec jau DB ir izdomatas lai glabatu shada veida informaciju ...

 

Faili skriptiem (programmam ) , un Lieliem datu masiviem ( lasi bildes ) DB informacijai ...

Link to comment
Share on other sites

Tajā txt failā useru datus gan nebija doma glabāt,tā ka failiņš būtu tikai viens kādus pāris Kb lielumā.Ar to ideju domāju 1 faila rindiņu ar jau gatavām tikai visām COUNT(*) vērtībām,kuras attiecas uz galvenās lapas informatīvo daļu.Viss info failā tiktu pārrakstīts tikai,kad notiek īstās tabulas kāda lauka update,sarakstot tajā vienā faila rindā COUNT(*) vērtības.Tā rindiņa izskatītos apmēram šādi: 40|23|567|57|u.t.t

Un tad bez pieslēgšanās db turpmāk tiktu viņš ielasīts masīvā katrreiz,kad tiek izsaukta index lapa. Masīvs[0] -forumu skaits,Masīvs [1]-aptauju skaits un tā visu vajadzīgo.Tam tak vajadzētu būt ātram variantam,bet ja vērtību būs ar laiku daudz,tad tā rindiņa būs jau pagara.Un grūtāk kadu papildus info vēl klāt sagabāt.Moš mēģināšu izbraukt pa kaut kā pa vidu starp txt un tabulu.Kur datu būs maz,likšu failiņu.Kur tā pavairāk-tad tabulā :)

Link to comment
Share on other sites

Lielu jēgu nesaskatu izmantot paralēli txt failus un db.

Ja to lietotāju ir maz, nejutīsi īpaši. Bet ja ap 1000 būs jau, tāds pasākums uz failiem sāks iebremzēt.

Un ja būs jau 10000, iebremzēs jūtami.

Grozies kā gribi, failu vienmēr būs jāielasa visu lai ar to strādātu.

Lai arī serveri paliek arvien ātrāki, tāda politika īsti vietā nebūs.

Failos var glabāt kādus settingus kopējos un tamlīdzīgi, bet ja izmanto failu lietotāju opcijām un tai pat laikā darbini db, mazliet aplam liekas.

Edited by mounkuls
Link to comment
Share on other sites

×
×
  • Create New...