Gå til innhold

mySQL og COUNT( * )


Anbefalte innlegg

Hvorfor returnerer

SELECT COUNT( * ) FROM `users` WHERE 1

Resource id #18?

 

Det er 6 rader i tabellen, og samme kode i phpMyadmin returner "6".

 

Fullstendig kode:

<?php

$connect = mysql_pconnect($connect_host, $connect_user, $connect_pass);
if(!$connect) {
echo "<p>Could not connect to host. Please try again later.</p>\n";
echo "<p>Error: ".mysql_error()."</p>";
exit;
}

$db = mysql_select_db($connect_db, $connect);
if(!$db) {
echo "<p>Could not connect to database. Please try again later.</p>\n";
echo "<p>Error: ".mysql_error()."</p>";
exit;
}

$rows = mysql_query("SELECT COUNT( * ) FROM `users` WHERE 1");

echo $rows;

?>

 

 

Har klødd meg i hodet i halve dag, men har ikke blitt noe klokere :hrm:

Endret av PT
Lenke til kommentar
Videoannonse
Annonse
Slå opp funksjonen mysql_fetch_array() ;)

Vi skrev visst dette ganske på likt.

 

Uansett, mysql_fetch_array er unødvendig. Den lager to array's, noe man sjeldent har bruk for. Man bruker som regel enten nummer, eller navnet på feltene. Sjeldent begge deler.

 

Å lage to array's er ikke bare overflødig, men tar også lengre tid.

 

Man kan selvfølgelig bruke mysql_fetch_array() sammen med MYSQL_ASSOC eller MYSQL_NUM, men siden MYSQL_BOTH er default, syntes jeg det var verdt å nevne.

 

Selv synes jeg mysql_fetch_assoc er den mest praktiske å bruke, mens mysql_fetch_array sammen med MYSQL_ASSOC i det andre argumentet (som result_type) er det raskeste.

Lenke til kommentar
Slå opp funksjonen mysql_fetch_array() ;)

Vi skrev visst dette ganske på likt.

 

Uansett, mysql_fetch_array er unødvendig. Den lager to array's, noe man sjeldent har bruk for. Man bruker som regel enten nummer, eller navnet på feltene. Sjeldent begge deler.

 

Å lage to array's er ikke bare overflødig, men tar også lengre tid.

 

Man kan selvfølgelig bruke mysql_fetch_array() sammen med MYSQL_ASSOC eller MYSQL_NUM, men siden MYSQL_BOTH er default, syntes jeg det var verdt å nevne.

 

Selv synes jeg mysql_fetch_assoc er den mest praktiske å bruke, mens mysql_fetch_array sammen med MYSQL_ASSOC i det andre argumentet (som result_type) er det raskeste.

Hehe... et lite tips, ikke start diskusjoner før du har valgt det rette selv. Ta en kikk på mysql_fetch_row() ;)

 

De fleste tutorials bruker mysql_fetch_array(), inkl. php maunalen så derfor synes jeg det er kjekt å referere til det som brukes mest. Dessuten på den spørringen så er det snakk om en array med kun to deler så det er ikke en gang en målbar forskjell. Uansett bra at du kommer med tips.

Lenke til kommentar

Oi, det snek seg inn en skrivefeil. Jeg mente selvfølgelig at mysql_fetch_array() sammen med MYSQL_NUM er det raskeste siden den lager en numererisk array.

 

Om du ser på setningen min ser du at den ikke gir noen mening. "Selv synes jeg mysql_fetch_assoc er den mest praktiske å bruke, mens mysql_fetch_array sammen med MYSQL_ASSOC i det andre argumentet (som result_type) er det raskeste". mysql_fetch_array med MYSQL_ASSOC er det samme som mysql_fetch_assoc. Jeg mente selvfølgelig å bruke MYSQL_NUM :)

 

mysql_fetch_array med MYSQL_NUM = mysql_fetch_row

mysql_fetch_array med MYSQL_ASSOC = mysql_fetch_assoc

Endret av RipZ-
Lenke til kommentar

Benchmark on a table with 38567 rows:

 

mysql_fetch_array

MYSQL_BOTH: 6.01940000057 secs

MYSQL_NUM: 3.22173595428 secs

MYSQL_ASSOC: 3.92950594425 secs

 

mysql_fetch_row: 2.35096800327 secs

mysql_fetch_assoc: 2.92349803448 secs

 

 

Sikkert noen som finner disse tallene interessante. Her ser man at selv om mysql_fetch_assoc gjør det samme som mysql_fetch_array med MYSQL_ASSOC i det andre argumentet, så er det faktisk en del å hente ved å bruke den egendefinerte funksjonen for dette. Det samme gjelder mysql_fetch_row.

Endret av RipZ-
Lenke til kommentar

Hvis du mener jeg tar feil er det bedre hvis du sier det i steden for å presentere tall som ikke sier brukere noe. Du forteller ikke en gang om spørringen, databasen eller scriptet.

 

Her kan jeg presentere et annet eksempel:

Dette er en database med ca. 100 000 rader:

 

mysql_fetch_row ca. 0.8

mysql_fetch_array ca. 1.28

mysql_fetch_assoc ca. 0.9

 

Dette er en ganske vanlig database med 9 felter inkl felttypene int, text og varchar.

 

I tillegg er dette på en vanlig pc og ikke en av serverene, så forskjellene vil egentlig bli mindre når de kjøres på et bedre system.

 

IKKE presenter tall uten nærmere forklaring. Som du ser så er din tabell MEGET missvisende for min tabell. Selv om jeg har en tabell som er ca. 2.5 ganger så stor så får jeg mye mindre forskjell. [EDIT] Tenker på antallet rader og ikke størrelsen i MB [/EDIT]

 

Vil ikke høres for streng ut, du gjør absolutt et poeng, og dette vil kunne bidra til raskere scripts dersom det er snakk om store scripts. Når det presenteres så tilfeldige tall så reagerer jeg litt. Vet heller ikke om mange scripts som trenger å hente ut rundt 38 000 rader ;)

 

Dette svaret er ikke for å direkte motsi ditt poeng, bare for å vise at forskjellene ikke er så store.

Endret av ????????
Lenke til kommentar

Disse tallene ble hentet fra PHP.net og var mer ment som en pekepinne for hvilke funksjoner som var raskest. Det jeg ville få frem var at de egendefinerte funksjonene var raskere enn å bruke mysql_fetch_array med et andre argument.

 

Enig i at det er dumt å presentere tall uten nærmere forklaring. Men i og med at dette kun var en copy/paste fra PHP.net (hvor det heller ikke stod noen nærmere forklaring) som ble dette en litt slurvete post fra min side.

 

Men for å få fram poengene mine:

 

- Å genrere èn array framfor to som er default med mysql_fetch_array(), er raskere.

- Å lage en array basert på nummer er raskere enn å basere arrayen på feltnavnene.

- De egendefinerte funksjonene er raskere enn å bruke mysql_fetch_array() med et andre argument.

 

Hvor mye differansen er mellom de forskjellige funksjonene er selvfølgelig avhengig av spørringen og antall rader. Selv bruker jeg alltid feltnavnet når jeg henter en verdi fra en mysql-tabell. Derfor bruker jeg alltid mysql_fetch_assoc framfor mysql_fetch_array.

 

Tror det kan være en god vane og venne seg til å bruke så målrettede funksjoner som mulig :)

Lenke til kommentar

Har jeg forstått det rett?

Du får det samme resultatet med array og row, men row er raskere.

 

Så om jeg har dette skriptet:

 

$top5 = mysql_query("SELECT * FROM tabell_navn ORDER BY date");
while($f_top5 = mysql_fetch_array($top5))
{
               $id = $f_top5['id'];
$name = $f_top5['name'];
               $email = $f_top5['email'];
$password = $f_top5['password'];
 $date = $f_top5['date'];
$posts = $f_top5['posts'];
    
$delete_by_id = $_POST['delete_by_id'];
 
 $delete = "DELETE FROM tabell_navn WHERE id = '$delete_by_id'"; 
mysql_query($delete) || die(mysql_error()); 



print('
<tr bgcolor="#FFFFCC"> 
</td>
 <td>  <input type="radio" name="delete_by_id" value=' .$id. '> 
</td>
 
 <td valign="top"><blockquote>' .$id. '
 </td>
 <td>  ' .$password. ' 
</td>
 <td>  ' .$name. '
</td>
 <td> ' .$email. '
</td>
 <td>' .$posts. '
</td>
<td>' .$date. '
</td>
     </blockquote>  
</tr>');
}

Og bytter array ut med row

while($f_top5 = mysql_fetch_row($top5))

 

Så blir resultatet akkurat det samme?

Lenke til kommentar

kudos til dere for å ha en av de mere matnyttige diskusjonene på dette forumet!

 

en naturlig fortsettelse vil være å ta en titt i php source.

her for eksempel:

http://no2.php.net/get/php-4.3.8.tar.gz/fr....php.net/mirror

 

jeg kan ikke så mye c programmering, men med litt intuisjon kommer man langt.

 

etter å ha pakket ut kildekoden, finner man fort ut at mysqlfunksjonene ligger i katalogen php-4.3.8/ext/mysql, og etter å ha søkt gjennom filene etter mysql_fetch_, ser det ut som om php_mysql.c er interessang.

 

Der finner man følgende funksjoner: (utklipp fra fila)

http://www.nt.ntnu.no/users/lindahl/mysql_fetch_.c.html

 

Alle de fire mysql_fetch_ kaller opp en felles funksjon, php_mysql_fetch_hash (som ikke er en phpfunksjon, men en intern c-funksjon)

 

mysql_fetch_obj gjør sannsynligvis mye annet rart, så den ser vi bortfra.

 

Men de tre andre ser ganske like ut.

Forskjellene er:

_row har ... MYSQL_NUM, 1);

_assoc har ... MYSQL_ASSOC, 1);

_array har ... 0, 2);

 

 

så langt er det ingenting som tyder på noen intern hastighetsfoskjell på disse tre. måten de er bygget opp på, virker også logisk.

 

MYSQL_ASSOC og MYSQL_NUM kan man gjette er konstanter, sannsynligvis integers (det er vanlig programmeringsskikk med store bokstaver for slikt) og brukes for som et slags "flag" for å angi til hash-funksjonen hva som skal gjøres videre.

 

Og ganske riktig, det står definert i samme fil:

#define MYSQL_ASSOC         1<<0
#define MYSQL_NUM           1<<1
#define MYSQL_BOTH          (MYSQL_ASSOC|MYSQL_NUM)

 

<< betyr "left shift" (vanlig i mange språk, også php) og vil si at bitene i byten skiftes til venstre x antall hakk ( i dette tilfellet 1 og 0). f.eks: 00000010 blir til 000000100 (dvs 2 blit til 4)

 

1<<1 blir 2, 1<<0 blir fortsatt 1, det er bare å prøve:

echo 1<<1;

 

| er binært OR, og virker slik for disse to tallene

   00000001 (binært for 1)
| 00000010 (binært for 2)
--------------
  00000011 (binært for 3)

 

binary OR sammenligner tallene bit for bit, 1 og 0 gir 1, 1 og 1 gir 1. Så MYSQL_BOTH er mao 3, mens de to andre er hhv 1 og 2

 

Så søker vi nedover i fila og finner php_mysql_fetch_hash:

http://www.nt.ntnu.no/users/lindahl/mysql_fetch_hash.c.html

(fra samme fil, men klippet ut bare funksjonsdefinisjonen)

 

Her ser vi at det er int result_type og expected_args som er interessange (disse var forskjellige for våre 3 funksjoner). kanskje mest result_type

 

Her er først et par variabel deklareringer, deretter noe med ZEND* og der ser det ut som om result_type settes til MYSQL_BOTH hvis den er 0.

 

& betyr binary AND, (analogt med binary OR) og fungerer akkurat som | bortsett fra at det er AND og ikke OR, dvs begge bitene må være sanne for å gi 1.

 

        if ((result_type & MYSQL_BOTH) == 0) {
               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH.");
       }

 

vi vet at MYSQL_BOTH er 00000011, så linja over sier at hvis vi har et argument som ikke har 01, 10 eller 11 i de to siste bitene (slik MYSQL_NUM og MYSQL_ASSOC og MYSQL_BOTH har) så er argumentet ugyldig. En errorsjekk mao.

 

result_type ser vi neste gang nede i forløkka.

                        if (result_type & MYSQL_NUM) {
                               add_index_stringl(return_value, i, data, data_len, should_copy);
                               should_copy = 1;
                       }
                       
                       if (result_type & MYSQL_ASSOC) {
                               add_assoc_stringl(return_value, mysql_field->name, data, data_len, should_copy);
                       }

 

Når vi husker på hvordan binary AND fungerer, ser vi at MYSQL_BOTH vil matche begge disse to if-setningene, _ASSOC og _NUM matcher henholdsvis sin respektive.

   00000001
& 00000011
-----------
  00000001 --> true

og

   00000010
& 00000011
----------
  00000010 --> true

 

Så heri ligger forskjellen på de to. mysql_fetch_array utfører begge operasjoner (som forventet). Det man kan lure på, er hvor mye det steget har å si for hele prosessen. Det gjenstår til den ivrige leser å undresøke videre funksjonene add_index_stringl og add_assoc_stringl fungerer.

 

EDIT: BBCode bugs

Endret av Torbjørn
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...