Jump to content
php.lv forumi

Kādus darba efektivitātes tūļus izmantojat?


codez

Recommended Posts

  • Replies 42
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

SELECT locid FROM geoip WHERE userip>=ip1 AND userip<=ip2

 

Kas tas par dīvainu queriju vispār...

 

Kā jau pēc konteksta varēja noprast, šis kverijs ir nepareizs, jo, ja mēs userip ieliekam tabulas pēdējo, pēc ip1 lielāko ip adresi, tad

salīdzinošā darbība userip>=ip1 izpildās pie katra no 3 miljoni ierakstiem un patiesībā datubāze apskata katru ierakstu un index šeit nekādi nepalīdz.

 

Pareizs kverijs būtu, ja mēs meklētu pēdējo ip1, kurš ir mazāks par userip, tad ar indexa palīdzību, tiek apskatīts tikai viens rows:

SELECT locid FROM geoip WHERE ip1<=userip AND ip2>=userip ORDER BY ip1 DESC LIMIT 1  ;

 

 

Ar šo piermēru gribēju parādīt, ka koda izpildes un kveriju laiku mērīšana atmaksājās, jo uzlabot kveriju prasīja pāris minūtes, bet reālāis skaitļošanas resursu ietaipījums ir salīdzinoši liels. Šijā gadījumā šis kverijs tērēja vairāk skaitļošanas resursu, kā viss pārējais tās lapas ģenerēšanas kods kopā.

Edited by codez
Link to comment
Share on other sites

un kaapeec tad domaa ka pareizi noindekseets lauks parskatiis visus ierakstus???

reaali vinjam buutu jaapanjem intervaals no Lidiz un ar tiem arii jaastraadaa ..

+ nav korekti saliidzinaat shos abus Kverijus jo pirmais var atgriest daudz ierakstus, bet otrais tikai 1 ... taa kaa..

Bet vispaar buutiba pareiza , sarezgjiitaaki kveriji IR japrabauda un biezji vien var parveidot indeksus & pashu kveriju ...

Link to comment
Share on other sites

LIMIT 1 šeit nav atslēgas frāze

 

Sliktais kverijs:

SELECT locid FROM geoip WHERE ip1<=userip AND ip2>=userip LIMIT 1 ;

 

Labais kverijs:

SELECT locid FROM geoip WHERE ip1<=userip AND ip2>=userip ORDER BY ip1 DESC LIMIT 1  ;

 

Lai saprastu atšķirību starp šiem jasaprot kā mysql izmanto indeksu.

Tā kā šijā gadījumā indeks bija PRIMARY KEY uz ip1 ip2 un indeksa tips binary tree.

ja mēs userip izvēlamies tādu, kas atbilst pēdējam ierakstam, tad 1. kverijā nosacījums ip1<=userip izpildās pilnīgi visiem ierakstiem un mysql datu bāzei ir jāapskata pilnīgi visi ieraksti, lai pārbaudītu katram arī atbilstošo ip2. Taču mums vienmēr ir vajadzīgs pēdējais ieaksts, kurš atbilst šim nosacījumam, tāpēc mēs vienkārši pieliekam ORDER BY ip1 DESC, lai mysql sāk meklēt no pēdējā vajadzīgā ieraksta, kurš arī būs mums nepieciešamais ieraksts un 2. gadījumā tiks apskatīts tikai 1 ieraksts, kurš tiks atgriezts.

Edited by codez
Link to comment
Share on other sites

un kaapeec tad domaa ka pareizi noindekseets lauks parskatiis visus ierakstus???

reaali vinjam buutu jaapanjem intervaals no Lidiz un ar tiem arii jaastraadaa ...

Binārais koks no līdz intervālu var paņemt tikai uz vienu lauku, bet šeit ir divi lauki ip1 un ip2.

Lai paņemtu no līdz uz diviem, tad ir jāizmanto SPATIAL index, bet šajā gadījumā tā būtu lieka ķēpa.

Link to comment
Share on other sites

Nedaudz patestēju, patiesībā, ja ieliek pēdējo ip vērtību sliktajā kverijā viss izpildās diezgan ātri, jo tad acīmredzot mysql apstaigā koku no otras puses. Visilgāk kverijs izpildās, ja no 3miljoni vērtībām, ieliek 1,5 miljono. Tad sliktā kverija izpildes laiks 1,5 s, savukārt labā kverija izpildes laiks 9 ms.

Link to comment
Share on other sites

normaalaa indekssaa tas IP glapaatos kaa skaitlju seciiba, kur katra skaitla atrasanaas vieta ir zinaama .. un Mysql nemaz neparbaudiitu paarejaas tikai panjemtu SAKOT NO un BEIDZOT ar pieprasiito ... tb kautkaadaa intervaalaa , protams ja tavs intervals nav no 1 - max Int vertiibai :(

taa kaa dodou 100% ka tev pashi index ir nepareizi salikti ..

Link to comment
Share on other sites

query optimizācija sākas ar execution plan analīzi, nevis cik tas ir ms.

ja vari, iemet abiem query, incē paskatīties.

Sliktajam:

1, 'SIMPLE', 'geo_block', 'range', 'PRIMARY', 'PRIMARY', '4', '', 1471555, 'Using where'

Labajam:

1, 'SIMPLE', 'geo_block', 'range', 'PRIMARY', 'PRIMARY', '4', '', 1471555, 'Using where'

 

 

Šeit jau tas āķis, ka EXPLAIN abiem ir vienāds, šeit vairāk tiek izmantots tas, ka es zinu kāda ir šī tabula un zinu, ka man vajadzīgais ieraksts, būs pēdējais, kuram ip1<=userip.

 

tev pirmais query no otrā atšķiras ar to, ka otrajam ir order by limit 1, kas bez limit 1 nedotu tev to efektu... ;)

Pat, ja pirmajam pieliek LIMIT 1 tas ir nemainīs būtību, jo ieraksts tiks atrast kā pēdējais no pārbaudāmajiem ierakstiem, bet otrajam LIMIT 1 ir vajadzīgs, jo mysql atradīs man vajadzīgo rowu kā pirmo, bet turpinās meklēt vēl rowus, lai gan tādus vairs nav, bet viņš to nezin, jo redz, ka ir vēl kaudze ierakstu kuriem ip1<=userip.

 

EDIT: tabulas lauki ir: ip1 ip2 locid, userip ir lietotāja ip adrese, kuras locid es vēlos atrast.

 

normaalaa indekssaa tas IP glapaatos kaa skaitlju seciiba, kur katra skaitla atrasanaas vieta ir zinaama .. un Mysql nemaz neparbaudiitu paarejaas tikai panjemtu SAKOT NO un BEIDZOT ar pieprasiito ... tb kautkaadaa intervaalaa , protams ja tavs intervals nav no 1 - max Int vertiibai :(

taa kaa dodou 100% ka tev pashi index ir nepareizi salikti ..

Šeit nav sākot un beidzot, jo ir divi fieldi ip1 un ip2, kur vienam mēs norādam ip1<=userip, tātad no pirmā ieraksts līdz userip, otram savukārt no userip līdz beigām. Bet binārais koks nevar divu fieldu intervālus apskatīt kā šijā brīdī tas indutīvi varētu šķist.

Edited by codez
Link to comment
Share on other sites

Bet īstenība jau runa nebija par domu gājienu, bet par to, ka kodu rakstīja cits, bet man viņš bija jāuzrauga un šādi tūļi palīdzēja momentāli atrast kļūdu un to likvidēt, tāpēc arī uzsāku šo topiku, jo iespējams ir kādi vēl labāki tūļi, par kuriem nekā nezinu.

Link to comment
Share on other sites


×
×
  • Create New...