Mūžu dzīvo, mūžu mācies
- 2007.10.19. 12:19
- Techy
Sauciet mani par losi un ņuņņu, bet es tik tiešām nezināju šo košo MySQL iespēju. Ņemsim par piemēru parastu lapošanu. Mums nepieciešams noskaidrot kopējo ierakstu skaitu un iegūt pēc tam attiecīgo daļu (lapu). Agrāk es rīkojos visvisādi. Lielākoties – divi identiski pieprasījumi. Bet, kā šodien noskaidroju, ir vienkāršāka metode.
SELECT SQL_CALC_FOUND_ROWS lauks, lauks2 FROM tabula ORDER BY lauks LIMIT 10, 10;
Un uzreizi pēc šī pieprasījuma, izveicam elementāru funkcijas izsaukumu:
SELECT FOUND_ROWS();
Un mēs iegūstam nevis atlasīto ierakstu skaitu (kas ir 10), bet gan visu atbilstošo ierakstu skaitu, kuru mēs iegūtu, ja nebūtu LIMIT daļas. MySQL Information Functions.

Komentāri (20)
Labs :) Šis man arī ir jaunums
Ar nezināju. Bet laikam arī tā pat līdz galam nesapratu kā tas strādā. Nākamreiz kad kaut ko tādu vajadzēs, paprovēšu pamāžoties.
Ne viss ir tik skaisti, kā sākumā liekas:
http://aggregator.foolab.org/node/13914
OK. Tu esi losis un ņuņņa. :D
Bet, jā, vispār, man arī savulaik bija sajūsma kad šito atklāju. :)
Mdā. Es ar nezināju. Turpmāk nebūs divu select`u.
Karoch. Es te izveicu pāris eksperimentus ar savas lapas datubāzi, selektēju komentus – tur man ir vietām posti, kur nenormāli daudz spamboti piedirsuši un es joprojām neesmu patīrijis. Attiecīgi tabulā ap 40k ierakstu. Testi liecina, ka tik tiešām ir tā kā tajā Ingus iemestajā linkā rakstīts – ar šito SQL_CALC_FOUND_ROWS pirmais kverijs izpildās ilgāk. Ne ļoti, bet katrā ziņā neizskatās, ka selects+selects-ar-count darbojas ātrāk.
Ingus: Tas tā varētu būt tik uz MyISAM tabulām, jo uz InnoDB COUNT() ir nejēgā lēns. Testējis gan neesmu.
ņuņņa
Ctrl+D. ;-)
Ir tikai viena bēda – šī ir MySQL-only fīča. Tā kā man pārsvarā sanāk darīšana ar Postgres un Firebird bāzēm, tad būs vien jāpaliek pie vecā labā count(*).
kaut kad sen biju atklājis, bet neiegājās to lietot un tā arī aizmirsu, varbūt nākamajā jaunajā projektā būs jāiesāk izmantot
Atklāju pirms pāris mēnešiem un biju ne mazāk priecīgs.
Vēlāk gan vīlos. Neatceros īsti par ko. Varbūt par to, ka procedūrās nevar īsti izmantot no PHP puses (bet divus mēnešus neesmu mēģinājis, neatceros).
tak Ingus iemeta saiti, kur parastais COUNT(*) izpogāja šito brīnumu
Veicu nelielu testu attiecībā uz ātrdarbību .
http://www.draugiem.lv/?pid=2719570#
Kristap, asprātīgi, protams.
Ja nav kaut kāds WHERE, tad labāk tos COUNT() pieglabāt kaut kur – vai nu DB, vai nu atmiņā… tiks viens SQL un/vai pārs updeiti…
klasiskais – lappošana pakategorijām – count * group by catid + (updeiti or memcache/etc)… Nafig katru reizi skaitīt ? Ja pie insertošanas var pārskaitīt un saglabāt.
ir ir selecti ar šo fīču mazliet lēnāki, bet kopā tāpat ātrāk nekā 2 selecti
–> DD: Saglabājot kaut kur pēc ievietošanas un dzēšanas vaicājumiem tik un tā vajadzēs izveikt atlases vaicājumu vai faila nolasīšanu. Protams tā nav skaitīšana, taču tik un tā. Sesijas ietvaros to vēl var glabāt kopā ar visu sesiju, izveicot sākuminicializāciju, taču tas var novest pie kļūdas datu izmaiņas gadījumā.
Te ir laba lapa: http://www.mysqlperformanceblog.com/
varbūt nezini par tādu…
Te ir konkrēti par tavu tēmu:
http://www.mysqlperformanceblog.com/2007/08/28/to-...
Blogs ir interesants, divi krievu džeki ņem cauri visādas advancētas MySQL lietas. Viens no viņiem bija “Manager of High Performace Group at MySQL Inc”, otrs bija “employed by MySQL Inc as Performance Engineer”. Tā kā nav nekādi lameri…
=> Didulis, pie datu izmaiņām veikt pārkalkulāciju… Glabāt to var N-tos veidos… memcache, faili, db … izvēlies ērtāko… Visos gadījumos būs pieejami jaunākie dati, jo tie ir šārētie resursi… Sessiju es nevienā vietā nepieminēju.
Protams, ja ir paredzams izmantot tikai Mysql un principā nekad citu DB, tad var izmantot arī šo fīču… Tādā gadījumā es neesmu pret.
Bet katru reizi veikt kalkulāciju, ja tas nav nepieciešams (bez WHERE nosacījumiem, vai daļēji sakešoti [piem., CATID_COUNT]), no perfomances viedokļa ir muļķīgi.
Ierakstīt savu sakāmo