Jump to content
php.lv forumi

qvēriju ātr::darbība..


eregi

Recommended Posts

Čau. Tā kaut kā aizdomājos un radās visādi jautājumi par qvērijiem un to `racionalitāti` (?)

Teiksim man ir tabula ar 15 laukiem, bet vajadzīgi man ir tikai divi. Tad ātrāk ir

$SQL = mysql_query("SELECT lauks1, lauks2 FROM db.table");
$row = mysql_fetch_array($SQL);

return $row['lauks1'].$row['lauks2'];

 

vai tomēr ņemt SELECT *

Itkā jau pirmais pēc loģikas, bet vēlos pārliecināties..

 

 

Tālāk

$SQL = mysql_query("SELECT COUNT(*) FROM db.table");
$row = mysql_fetch_array($SQL);

return $row['COUNT(*)'];

#---------- vai

$SQL = mysql_query("SELECT * FROM db.table");
$count = mysql_num_rows($SQL);

return $count;

 

Kurš tad no šiem ir ātrāks un vai ir kāds ātrāks veids, kā uzzināt ierakstu daudzumu tabulās? Teiksim, cik domāju pirmais variants ir ātrāks, bet, kuros gadījumos lietojam mysql_num_rows? :)

 

 

Tālāk, vai, kas īpašs palīdz izvēlēties starp mysql_fetch_array un mysql_fetch_assoc ?

 

Varbūt ir vēl kādi sīkumi, kurus varat ieteikt, kā veidcojat qvērijus? Pieraksts, u.t.t.

 

++ kā notiek reāli dzīvē tā datu selectošana. Viss tiek vilkts ārā no db tajā brīdī, kad palaižu mysql_fetch_array?

Teiksim, ja man ir

$SQL = mysql_query("SELECT Name  ...");
$row = mysql_fetch_array($SQL);

echo $row['Name'];

/*

Pagarš koda gabals

*/

echo mysql_num_rows($SQL);

 

vispār, ja godīgi, pēdējā piemērā es `sapisos meistarībā` :)

Būtība tāda - varbūt kaut ko varat pastāstīt, kas palīdzētu iegūt laiku?

 

btw ja nu kaut kur kāds c par daudz, tad ziniet - man klaviatūra nedaudz salauzta, c iespiežas, kad grib.

 

EDIT: vispār bubu vai kāds, kurš vēl gar to forumu grābstās, nevarat lūdzu uzlikt

 tagus? Nu tā, lai ievietotais kods tiktu highlightots.
Edited by eregi
Link to comment
Share on other sites

vai tomēr ņemt SELECT *

Itkā jau pirmais pēc loģikas, bet vēlos pārliecināties..

Atšķirības jutīsi tikai pie lielas slodzes. Taču prātīgāk vienmēr ir pieprasīt tikai tos datus, kuri ir nepieciešami.

 

Kurš tad no šiem ir ātrāks un vai ir kāds ātrāks veids, kā uzzināt ierakstu daudzumu tabulās?

Tas pats, kas iepriekš - pieprasi tikai tos datus, kuri nepieciešami. Tev vajadzīgs ierakstu skaits - pieprasi ierakstu skaitu, nevis visas tabulas visus datus.

 

> bet, kuros gadījumos lietojam mysql_num_rows? :)

Piemēram, tev ir nepieciešams kverijs, kas izvelk no tabulas visus datus un attēlo to weblapā (echo). Bet pie reizes datu apstrādē vajadzīgs skaits kaut kam. Tad tā vietā, lai taisītu divus kverijus (SELECT * un SELECT COUNT(*)) tu iztaisi vienu (to pirmo) un tad attiecīgi ar mysql_fetch_xxx izvelc ierakstus, un ar num_rows - skaitu.

 

 

Tālāk, vai, kas īpašs palīdz izvēlēties starp mysql_fetch_array un mysql_fetch_assoc ?

Ātrdarbības ziņā diez vai jutīsi atšķirību. Bet nu, ja lieto tikai vienu veidu kā piekļūt laukiem (asociatīvo?), tad kāpēc tev vajag skaitliskos indeksus? Paskaties manuālī atķirību.

 

++ kā notiek reāli dzīvē tā datu selectošana. Viss tiek vilkts ārā no db tajā brīdī, kad palaižu mysql_fetch_array?

Tas viss ir aprakstīts dokumentācijā (manuālī).

Php to dara mysql_query funkcijā, t.i savelk visus datus no DB uz php). Visas pārējās fetch_xxx fjas jau atgriež datus, kas savilkti atmiņā.

Ja gribi, lai dati velkas no DB ar katru fetch_xxx izsaukumu ietaupot atmiņu lieliem kveriju rezultātiem, tad jālieto unbuffered_query fja.

 

 

(kodu raksta ar [ code ] bbtagu, nevis

)
Link to comment
Share on other sites

Bubu, biju domājis noriskēt vai vēl ir

 tagi, un nepaspēju editot pirms Tu ienāci ( par brīnumu ). 
Apsties mana posta editēto daļu par highlightosanu.

Tātad tajā otrajā gadījumā ātrākais būs

[code]$SQL = mysql_query("SELECT COUNT(*) FROM db.table");
$row = mysql_fetch_array($SQL);

return $row['COUNT(*)'];[/code]

 

?

 

Bet vai pēķšņi vēl ātrāks nebūtu

 

[sql]SELECT COUNT(*) ...[/sql]

 

nomainīt pret

[sql]SELECT COUNT(Id) ..[/sql]

 

Laikam šajā gadījumā pirmais ( COUNT(*) ) ir ātrāks, jo netiek konkrēti dati ņemti, bet vienkārši pajautāts serverim, cik ieraksti. yes?

 

EDIT:

Vēl ienāca viena muļkība prātā -

vai ir jēga veidot jaunu klasi ar mysql funkcijām teiksim

[code]class db
{
function fetch($line)
{
// te kaut kāda $line tīrīšana / eskeipošana
$SQL = mysql_query($line);
$ret = mysql_fetch_array($SQL);

return $ret;
}
}[/code]

Nezinu vai no tā ir kāda jēga, varbūt tikai kāda ieekanomēta rinda. Vai kāds kaut ko tamlīdzīgu dara?

Edited by eregi
Link to comment
Share on other sites

Bet vai pēķšņi vēl ātrāks nebūtu

 

SELECT COUNT(*) ...

 

nomainīt pret

SELECT COUNT(Id) ..

 

Laikam šajā gadījumā pirmais ( COUNT(*) ) ir ātrāks, jo netiek konkrēti dati ņemti, bet vienkārši pajautāts serverim, cik ieraksti. yes?

 

Šai gadījumā nevajag teoretizēt, bet skatīties izpildes plānu. Kā MySQLā iegūt izpildes plānu var redzēt šeit. Ja izpildes plāns abiem SQL teikumiem sakrīt, tad izpildes ātrums abiem, protams, būs vienāds.

Un tātad, ja šī kolona ID būs primārā atslēga, tad tas visticamāk sakritīs.

mysql> create table c (id int primary key);
Query OK, 0 rows affected (0.05 sec)

mysql> explain select count(*) from c;
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+
| id | select_type | table | type  | possible_keys | key	 | key_len | ref  |
rows | Extra	   |
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+
|  1 | SIMPLE	  | c	 | index | NULL		  | PRIMARY | 4	   | NULL |
  1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+

mysql> explain select count(id) from c;
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+
| id | select_type | table | type  | possible_keys | key	 | key_len | ref  |
rows | Extra	   |
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+
|  1 | SIMPLE	  | c	 | index | NULL		  | PRIMARY | 4	   | NULL |
  1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+
-----+-------------+

 

Ja kolona ID nebūs primārā atslēga, tad, protams, situācija ir pavisam citāda.

mysql> create table d (id int, real_id int primary key);
Query OK, 0 rows affected (0.03 sec)

mysql> explain select count(id) from d;
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows
| Extra |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
|  1 | SIMPLE	  | d	 | ALL  | NULL		  | NULL | NULL	| NULL |	1
|	   |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------+
mysql> explain select count(*) from d;
+----+-------------+-------+-------+---------------+---------+---------+------+-
-----+-------------+
| id | select_type | table | type  | possible_keys | key	 | key_len | ref  |
rows | Extra	   |
+----+-------------+-------+-------+---------------+---------+---------+------+-
-----+-------------+
|  1 | SIMPLE	  | d	 | index | NULL		  | PRIMARY | 4	   | NULL |
  1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+-
-----+-------------+

 

Tātad kāpēc?

 

Tāpēc, ka ir jāizprot, ko dara grupēšanas funkcija count(<izteiksme>). Grupēšanas funkcijas ņem vērā tikai tās izteiksmes, kur vērtība nav NULL. Tā kā * vienmēr nav NULL, tad tas ir ekvivalents, ja ieliek kā izteiksmi primārās atslēgas kolonu. Savukārt gadījumā, kad id ir parasta neprimārās atslēgas kolona, kas piedevām var būt NULL, tad nekas, cits neatliek kā noskaidrot cik tad vērtības šai kolonai nav NULL un tās saskaitīt.

 

Gints Plivna

http://datubazes.wordpress.com

Link to comment
Share on other sites

Gint, skaidrs tā arī domāju. Itkā jau man (laikam?) katrai tabulai ir primārā atslēga Id, tātad es varētu veikt COUNT(Id), bet ja Tu saki, ka nav atšķirība starp COUNT(Id) un COUNT(*), tad es radināšos pie COUNT(*). Paldies Tev!

Link to comment
Share on other sites

Joka pēc izdomāju pamēģināt inner join ( visu vienmēr veidoju ar prastiem kvērijiem ).

Tabula 1 ( pilsēta )

+----+-----------+--------+-------+---------------------+------+------+
| Id  | Cover	 | sTitle   | Title   | Date				 | A_id  | Ip   |
+----+-----------+--------+-------+---------------------+------+------+
|  1 | fails.jpg | Riga		| NULL  | 2009-05-20 16:32:38 |	1 | ip   |
|  2 | fails.jpg | Liepāja	| NULL  | 2009-05-20 16:32:38 |	1 | ip   |
|  3 | fails.jpg | abcdefg   | NULL  | 2009-05-20 16:33:05 |	1 | ip   |
|  4 | fails.jpg | abwetc	| NULL  | 2009-05-20 16:33:05 |	1 | ip   |
+----+-----------+--------+-------+---------------------+------+------+

 

tabula 2 ( pilsētu iedzīvotāji )

+----+------+--------------+-----------+
| Id  | P_id  | Name			   | Surname	|
+----+------+--------------+-----------+
|  1 |	1		| Jānis			| Uzvārdcs |
|  2 |	2		| Aldis			| Uzvārdcs |
|  3 |	1		| Jēkabs		 | Uzvārdcs |
|  4 |	2		| Anete		  | Uzvārdcs |
|  5 |	4		| Agnese		| Uzvārdcs |
|  6 | 55	  |Valdis		   | Uzvārdcs |
+----+------+--------------+-----------+

Vienvārdsakot, viena tabula ir pilsētas, otra iedzīvotāj, kuri tur dzīvo.

Vajag to visu izvadīt ārā. Ok, kvērijs varētu būt tāds

SELECT city.Id,city.Cover,city.sTitle,people.Title FROM db.city INNER JOIN db.people ON city.Id = P_id

Tam visam beigaš pievienoju GROUP BY city.Id, lai tiktu grupēts pa pilsētām. Tik tālu (laikam?) viss ir ok.Tālāk rodas problēmas pie izvades.

Vēlos, lai tiktu izvadīts, pilsētas id, Cover, sTitle, un katra cilvēka Vārds.

 

teiksim P_id = 1; Cover = fails.jpg; sTitle = Riga; Un tad teiksim pie šīs pilsētas piederās 2 iedzīvotāji, tātad, tiek izvadīts Jānis un Jēkabs; jautājums, vai tos iedzīvotājus tā var izvadcīt? Jo ar pašreizējo qvēriju tiek izvadīts, pirmais iedzīvotājs no katras pilsētas.. Kods aptuveni tāds -

$SQL = db::get("SELECT city.Id,city.Cover,city.sTitle,people.Title FROM db.city INNER JOIN db.people ON city.Id = P_id GROUP BY city.Id");
while($row = mysql_fetch_array($SQL))
{
	return "te visa izvade"; 
}

 

Nu vot tā. interesēja vai to var panākt bez vēl viena cikla veidošanas.

Edited by eregi
Link to comment
Share on other sites

Vēl ienāca viena muļkība prātā -

vai ir jēga veidot jaunu klasi ar mysql funkcijām teiksim

class db
{
function fetch($line)
{
	// te kaut kāda $line tīrīšana / eskeipošana
	$SQL = mysql_query($line);
	$ret = mysql_fetch_array($SQL);

	return $ret;
}
}

Nezinu vai jega veidot Atseviskju klasi, bet atseviskjas funkcijas kas apstradaa SQl datus ir gan jega ...

jo: var visu SQL funkciju grupu sakopot vienaa koda gabalaa, un talak jau peec vajadziibas izmantot ...

teiksim Gadijumos kad vajag no DB dabuut 1 ( VIENU ierakstu) ir jega izveidot atseviskju funkciju peec piemera :

function sql_select_1($query)
{
$result= mysql_query($query);
$row=mysql_fetch_array($result);
mysql_free_result($result);
return $row;
}

kaa redzams kopaa jaizmanto buutu 3 koda rindas , ertiibas labat viss tiek aizstaats ar vienu ....

vel piemers kad janosaka ierakstu skaits ( peec kaada nosacijuma)

function chek_ekssitejoshos($db,$where='1')
{
 $sql="SELECT count(*) AS skaits FROM $db WHERE $where";
 $result= mysql_query($sql);
 $row=mysql_fetch_array($result);
 mysql_free_result($result);
return $row['skaits'];
}
// un padodam Tikai tabulas nosaukumu un nosacijumu ( vai pat bez taa )
$skaits=chek_ekssitejoshos('tabulas_nosaukums'); // taatad saisinam kodu un padaram to parskatamaaku

Bet vai to visu Likt atseviskjaa klasee, tas jau vairak gaumes jautajums...

Link to comment
Share on other sites

Tev izvadās tikai pirmais iedzīvotājs, jo tu lieto GROUP BY. Tur nevajag GROUP BY lietot, tas dara pavisam ko citu.

Ja tu gribi sakārtot datus pēc pilsētas nosaukuma, tad jālieto SORT BY city.Id (vai sTitle).

Link to comment
Share on other sites

Ah, laikam sūdīg paskaidroju, ko vajag. Tātad pašlaik mysql console parāda kaut ko šādu -

 

mysql> SELECT * FROM db.city INNER JOIN db.people ON city.Id = P_id;
+----+-----------+--------+-------+---------------------+------+------+----+------+--------------+-----------+
| Id | Cover	 | sTitle | Title | Date			   | A_id | Ip	  | Id  | P_id  | Name		| Surname |
+----+-----------+--------+-------+---------------------+------+------+----+------+--------------+-----------+
|  1 | fails.jpg | Rīga	 | NULL  | 2009-05-20 16:32:38 |	1 | ip	|  1  |	1   | Jānis		   | Uzvārdcs  |
|  1 | fails.jpg | Rīga	 | NULL  | 2009-05-20 16:32:38 |	1 | ip	|  3  |	1   | Jēkabs	   | Uzvārdcs  |
|  2 | fails.jpg | Liepāja| NULL  | 2009-05-20 16:32:38|	1 | ip	|  2  |	2   | Aldis		   | Uzvārdcs  |
|  2 | fails.jpg | Liepāja| NULL  | 2009-05-20 16:32:38|	1 | ip	|  4  |	2   | Anete		   | Uzvārdcs  |
|  4 | fails.jpg | abwetc| NULL  | 2009-05-20 16:33:05|	1 | ip	|  5  |	4   | Agnese	   | Uzvārdcs  |
+----+-----------+--------+-------+---------------------+------+------+----+------+--------------+-----------+

 

Mēģinu ar to pašu kvēriju izvadīt datus caru php.

Vēlreiz, kā vēlētos, lai php attēlotu -

 

Rīga - Jānis

Jēkabs

Liepāja - Aldis

Anete

abwetc - Agnese

 

 

Pagaidām nezinu kā to varētu attēlot izmantojot 1 kvēriju.

Tā to visu varētu vnk ielikt iekš while, dabūt Datus par pilsētu, tad iekš while ielikt vēlvienu qvēriju, kurš atkal ar while attēlotu iedzīvotājus, un tā katrai pilsētai. Bet kā to visu vienkāršot == 1kvērijs vai nu kaut kas tamlīdzīgs?

Edited by eregi
Link to comment
Share on other sites

Protams, ka var ar vienu kveriju.

Ņem vērā, ka kverijs tikai atvelk datus. To kā tu tos izvadīsi ir php ziņā, tur tad implementē attiecīgo loģiku:

$pēdējā_pilsēta = "";
while ($row = mysql_fetch_xyz($q))
{
$vārds = $row["Name"];
$pilsēta = $row["sTitle"];
if ($pēdējā_pilsēta != $pilsēta)
{
	echo "$pilsēta - $vārds <br/>";
	$pēdējā_pilsēta = $pilsēta;
}
echo "$vārds <br/>";
}

Link to comment
Share on other sites

Tas darbojas tieši tāpat, kā jebkurš cilvēks rīkotos, ja viņam iedotu pilsētu-cilvēku sarakstu, un liktu uzrakstīt uz lapiņas to tādā formā, kā tu tur gribi.

Ja iepriekšējā pilsēta ir vienāda ar patreizēji rakstāmā cilvēka pilsētu, tad tā vienkārši tiek neizvadīta. Visa māksla.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...