RSS

Świat Owoców — remont

Liczba odsłon: 18

Wczoraj i dzi­siaj prze­pro­wa­dzi­łem drob­ny „re­mont” w Świecie Owo­ców. Przeróbce uleg­ły prze­de wszyst­kim za­py­ta­nia SQL ge­ne­ru­ją­ce głów­ną stro­nę ser­wi­su. Dokona­łem też dłu­go od­kła­da­nej aktu­ali­zac­ji inter­pre­te­ra ję­zy­ka PHP.

W związku ze zmia­na­mi mo­gą oczy­wiś­cie po­ja­wić się róż­ne­go ty­pu nie­do­god­noś­ci, od nie­spo­dzie­wa­nych ko­mu­ni­ka­tów ge­ne­ro­wa­nych przez inter­pre­ter PHP, aż po nie­pra­wid­ło­we funkcjo­no­wa­nie nie­któ­rych mo­du­łów ser­wi­su. W ra­zie na­pot­ka­nia ta­kich prob­le­mów pro­szę o kon­takt.

Przy okaz­ji mu­szę nie­co po­na­rze­kać na wy­daj­ność sys­te­mu ba­zo­da­no­we­go MySQL. Dopóki ko­rzys­ta się z pros­tych za­py­tań, MySQL po­tra­fi bić na gło­wę wie­le in­nych sys­te­mów ba­zo­da­no­wych, włącz­nie z „gi­gan­ta­mi” w ro­dza­ju Oracle czy Microsoft SQL Server. Wystar­czy jed­nak jed­no bar­dziej skom­pli­ko­wa­ne za­py­ta­nie, by spro­wa­dzić MySQL do par­te­ru. Co gor­sza, pró­by opty­ma­li­zo­wa­nia ta­kie­go za­py­ta­nia mo­gą spa­lić na pa­new­ce z po­wo­du bra­ku im­ple­men­tac­ji nie­któ­rych ele­men­tów ję­zy­ka SQL lub po­waż­nych ogra­ni­czeń w ich im­ple­men­tac­ji.

Dla przy­kła­du, do­tych­czas głów­na stro­na ser­wi­su była bu­do­wa­na pros­tym za­py­ta­niem po­bie­ra­ją­cym in­for­mac­je o dzie­się­ciu naj­now­szych wpi­sach pa­su­ją­cych do wy­bra­ne­go przez użyt­kow­ni­ka filt­ra. Następ­nie dla każ­de­go wpi­su z osob­na po­bie­ra­ne były in­for­mac­je o ostat­nim do­ty­czą­cym go ko­men­ta­rzu. Rozwiąza­nie to było zde­cy­do­wa­nie nie­ele­ganc­kie i bar­dzo roz­rzut­ne. Wprowadzona zmia­na po­le­ga­ła na wy­ko­rzys­ta­niu ze­spo­le­nia (JOIN), łą­czą­ce­go ta­be­le wpi­sów i ko­men­ta­rzy (po za­led­wie ty­siąc rekordów każ­da). Efekt? Nie ta­kie zno­wu skom­pli­ko­wa­ne za­py­ta­nie, wy­wo­ły­wa­ne przecież przy każ­dym otwar­ciu głów­nej stro­ny ser­wi­su, trwa­ło po­nad pół­to­rej se­kun­dy!

Co gor­sza, zopty­ma­li­zo­wa­nie tego za­py­ta­nia oka­za­ło się po­waż­nym prob­le­mem. MySQL nie ob­słu­gu­je bo­wiem wy­ra­że­nia LIMIT w za­py­ta­niach za­gnież­dżo­nych. Można oczy­wiś­cie wy­ge­ne­ro­wać tym­cza­so­wą tablicę da­nych, za­peł­nić ją właś­ci­wy­mi in­for­mac­ja­mi i za­stą­pić za­py­ta­nie za­gnież­dżo­ne od­wo­ła­niem do tab­li­cy tym­cza­so­wej, jed­nak MySQL nie po­zwa­la na wie­lo­krot­ne od­wo­ły­wa­nie się do tab­li­cy tym­cza­so­wej w ra­mach jed­ne­go za­py­ta­nia. Koszmar...

Gdy tyl­ko będę miał tro­chę cza­su, spró­bu­ję prze­pro­wa­dzić po­rów­na­nie wy­daj­noś­ci i funkcjo­nal­noś­ci MySQL oraz PostgreSQL, uwa­ża­ne­go obec­nie za naj­szyb­szy i naj­bar­dziej zgod­ny ze stan­dar­da­mi sys­tem ba­zo­da­no­wy open-source. Już teraz mam jed­nak prze­czu­cie, że PostgreSQL wygra ten po­je­dy­nek.


Jeżeli dobrze rozumiem, to skoro MySQL nie obsługuje LIMIT w zapytaniach zagnieżdżonych, to można je rozdzielić na dwa-trzy-ileśtam zapytań. I wtedy LIMIT będzie działał.
Wydaje mi się, że autor chciał uniknąć wielokrotnych zapytań i rozwiązać sprawę w jednym, więc podział na kilka zapytań to prawie że wrócenie do punktu wyjścia.
Chodziło mi o to, by zminimalizować liczbę zapytań. Oczywiście, wziąłem pod uwagę wydzielenie zapytania zagnieżdżonego, ale – jak napisałem we wpisie – MySQL pozwala odwołać się do niego tylko raz, a ja potrzebowałem dwóch odwołań do tego samego wyniku w jednym zapytaniu.
Obecnie odwołuję się raz do wydzielonego, a raz dodatkowo je wykonuję i wydajność jest akceptowalna (poniżej 200 milisekund), ale to i tak niezbyt szybkie i na pewno nieeleganckie rozwiązanie.