Corectați numărătoarea () în mysql - notele din album

Din când în când, citirea codului altcuiva, văd că unii dezvoltatori specifică diferiți parametri în funcția COUNT () pentru a obține numărul de rânduri.
De exemplu: numără (*), numără (id) (unde id este cheia primară). număr (0).






Se ridică întrebarea: "Ce număr () este corect? Și care sunt pseudo-contele?
Pentru baza "corectitudinii" a luat viteza interogării.
Am completat 3 cereri:


În toate cele trei, timpul de rulare a fost de 0,03-0,04 sec. și, destul de ciudat, același rezultat - numărul 47915774.

S-au găsit în documentație următoarele:

Merită remarcat faptul că pentru lipsa altora am făcut teste pe tabelul MyISAM.

De fapt, nu este nimic surprinzător aici, așa că mergem mai departe.
Există un câmp index pe plăcuța de identificare
`c_time` datetime NOT NULL implicit '0000-00-00 00:00:00'

Execut aceleași 3 cereri, dar cu restricția pe c_time:

În primele două cazuri obținem timpul de execuție a interogării de la 2,84 la 3,15 sec, iar în a treia parte 27,46 - 28,34 (.) Sec.

Fac apel la sanctuarul interior al MySQL-guru - EXPLICAȚI cerere și să recunoască faptul că, în acest din urmă caz, în câmpul „luminile“ Extra „Utilizarea în cazul în care“, în timp ce în primele două interogări arată Extra „Utilizarea în cazul în care; Cu ajutorul indexului“.

Pe această notă tragică, testele mele s-au terminat.
Este interesant să se uite la rezultate similare în interogări în care WHERE este executat pe un câmp non-cheie, precum și pe tabele non-MyISAM.

P.S. Apropo, eu însumi, dintr-un motiv necunoscut pentru mine, folosiți numărul (*).

19 Răspunsuri la "Contorul corect () în MySQL"

Rețineți că dacă utilizați indexul atunci când preluați numărul de rânduri printr-o interogare
SELECT COUNT ( `id`) ca cnt din` users` UTILIZARE INDEX (as_id) UNDE` siteuser` = 1“. ȘI `active` = 1 ':
atunci timpul de execuție este mai mic decât numărul (*) și numărul (0), adică când se utilizează indexuri, este mai bine să se folosească "id"






Am un as_id idem egal cu un pachet de id, siteuser și coloane active.

as_id este egal cu pachetul de id, siteuser și coloane active.

Și de ce id acolo să pună?
Cred că id-ul are o cheie primară, care, de fapt, este un indice.

da, dar eșantionarea se face nu numai în primari, ci și în site-ul și activ

dar eșantionarea se face nu numai în primari, ci și în situser și activ

Și dacă faceți o selecție a tuturor combinațiilor de 5 câmpuri - veți avea 120 de indici cu toate combinațiile de câmpuri pe care să le creați?

Ce împiedică MySQL să utilizeze 2 indici?
Prima este cheia primară (id), a doua cheie (siteuser, activă)
Sau chiar 3: cheia primară (id), a doua cheie (siteuser), cheia (activă)?

Ideea de a adăuga un id la indexul compus este pur și simplu nu: dacă un id este specificat, MySQL va folosi cheia primară și nici măcar nu se va uita la ceilalți indici.
Dacă id-ul nu este specificat în interogarea dvs., atunci indexul dvs. compozit va fi, de asemenea, ca un obturator mort, deoarece indexul pentru perechea (siteuser, activ) pe care nu îl aveți, există doar un triplet (id, siteuser, activ).

O întrebare bună care o împiedică, pentru că el nu le folosește.
Și făcând un indice compozit și indicând folosirea lui, am realizat o schimbare a vitezei interogării de la 8 secunde la 0,7 secunde.
Există hrană pentru creier.

De ce MySQL nu utilizează indexul este un subiect separat, iar funcția COUNT nu se aplică.
Este foarte posibil ca numărul estimat de rânduri în rezultatul a fost mai mult de 15-20% din numărul total - în acest caz, de optimizare a crede că este mai bine să-și petreacă tabelul fullscan puteți utiliza indici. Dar uneori el se înșeală.

P.S. Sper că întrebarea este de ce nu este necesar să adăugați o cheie primară la indexul compozit nu mai merită?

mulțumesc, postul a ajutat foarte mult.
Apoi m-am bazat pe sanatatea mysql-ului de optimizare intern.
nu foarte mult în șoc, un secol, trăiesc secolul învăța. - |

EXPLAIN SELECT NUMĂRUL SQL_NO_CACHE (0)
Din "știri"
WHERE "type" = 2

id | select_type | table | type | possible_keys | key | key_len | ref | rows | extrara
1 | SIMPLE | nou | tip | tip | 4 | const | 8623 | Folosind unde; Utilizarea indexului

și la numărul (id) avem doar Utilizarea unde sunt întârzieri mari.

Câte linii există în tabel?
Câte dintre ele se încadrează în condiția "type" = 2?
Ce tip are câmpul de tip?
A construit un index?

Există o suspiciune că numărul de (0) Instrumentul de optimizare a decide că este mai ieftin să efectueze fullscan toate tabelele în loc de a folosi un index (astfel de lucruri se întâmplă în cazul în care numărul preconizat de înregistrări depășește 20-25% din total).
De ce în acest caz nu se întâmplă la numărul (id) - este greu de spus.







Trimiteți-le prietenilor: