Java Posted November 13, 2008 Report Share Posted November 13, 2008 Kas tas par dīvainu queriju vispār... Un tu gan esi norūpējies par savu nūģismu :D Link to comment Share on other sites More sharing options...
bubu Posted November 13, 2008 Report Share Posted November 13, 2008 Normāls kverijs, kāpēc dīvains? Atrod zināmai IP adresei atbilstošo ierakstu, kuram tā atbilst. Tabulas ieraksti satur IP adrešu intervālus [ip1..ip2]. Link to comment Share on other sites More sharing options...
codez Posted November 13, 2008 Author Report Share Posted November 13, 2008 (edited) 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 November 13, 2008 by codez Link to comment Share on other sites More sharing options...
Java Posted November 14, 2008 Report Share Posted November 14, 2008 Very tricky. Link to comment Share on other sites More sharing options...
Grey_Wolf Posted November 14, 2008 Report Share Posted November 14, 2008 codez --> kaada formaataa glabaa tos Ip ?? Link to comment Share on other sites More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 ip formāts integer Link to comment Share on other sites More sharing options...
Grey_Wolf Posted November 14, 2008 Report Share Posted November 14, 2008 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 More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 (edited) 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 November 14, 2008 by codez Link to comment Share on other sites More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 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 More sharing options...
Java Posted November 14, 2008 Report Share Posted November 14, 2008 codez - spatial index un miljardiem dolāru vērti web projekti - tās ir vienīgās lietas, ko tu no sevis esi parādījis šeit ar visu savu ūberlielo plātīgumu! Link to comment Share on other sites More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 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 More sharing options...
Grey_Wolf Posted November 14, 2008 Report Share Posted November 14, 2008 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 More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 (edited) 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 November 14, 2008 by codez Link to comment Share on other sites More sharing options...
codez Posted November 14, 2008 Author Report Share Posted November 14, 2008 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 More sharing options...
marrtins Posted November 14, 2008 Report Share Posted November 14, 2008 Ko jūs darītu, ja jums jānosaka valsts 20`000 IP adresēm? Link to comment Share on other sites More sharing options...
Recommended Posts