Problema query MySQL

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
Salve a tutti,

ho un database MySQL con una tabella che ha quasi 200000 righe e 25 colonne, uso EasyPHP per fare le mie prove in locale, un campo è di tipo data 'Y-m-d', la mia quey è la seguente :

$query = "SELECT * FROM TABELLA WHERE giorno >= '$date1' AND giorno <= '$date2'";

il problema è che se l'arco di tempo tra $date1 e $date2 è elevato, non mi restituisce il risultato, e cioè almeno vorrei sapere quante righe sono con un semplice count.
Mi ritrovo con l'errore di aver superato il limite massimo di tempo per la query.

Potete aiutarmi in qualche modo ?

Ringrazio tutti anticipatamente.
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
per vedere quante righe sono
PHP:
<?php
//.....
$query = "SELECT * FROM TABELLA WHERE giorno >= '$date1' AND giorno <= '$date2'";
$ris=mysql_query($query);
$le_righe_sono=mysql_num_rows($ris);
//....
?>
se poi il tempo di elaborazione è troppo lungo puoi allungare la vita dellp script (standard 30 sec) con
PHP:
set_time_limit ( $secondi ); //$secondi numero intero di secondi es 3600 (01 ora)

però forse la soluzione migliore è fare una paginazione in modo da estrarre un numero limitato di record alla volta
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ciao,
prova anche con BEETWEN dovrebbe essere piu veloce

PHP:
$query = "SELECT * FROM TABELLA WHERE giorno BETWEEN '$date1' AND '$date2'";

se ti interessano anche i dati compresi della variabile $date2 devi aggiungere

PHP:
$query = "SELECT * FROM TABELLA WHERE giorno BETWEEN '$date1' AND DATE_ADD('$date2',INTERVAL 1 DAY)";
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
prima di tutto, grazie per le risposte, molto gentili, ma il problema si è complicato.

Avevo risolto quel problema eliminando altre situazioni che esistevano prima, praticamente ho alleggerito tyutto il codice facendo fare a questa pagina solo questo.
Ora ho :

$query = "SELECT e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20 FROM 'TABELLA' WHERE giorno >= '$date1' AND giorno <= '$date2'";
$result = mysql_query($query);
$row = mysql_num_rows($result);// NUMERO DI RIGHE

e fin qui ci siamo, va bene, poi :

while ($row = mysql_fetch_array($result, MYSQL_NUM)) {


$query = "SELECT e1, e2 FROM 'ALTRA TABELLA'";
$result1 = mysql_query($query);

while ($row1 = mysql_fetch_array($result1, MYSQL_NUM)) {
$numero1 = $row1[0];
$numero2 = $row1[1];

if (in_array($numero1,$row ) && in_array($numero2,$row )) {
$coppia[$numero1][$numero2] = $coppia[$numero1][$numero2] + 1;
}

}


Praticamente ho bisogno di sapere quante volte escono quei due numeri in quel range di giorni.

Facendo la prima query tra pochi giorni di distanza TUTTO VA BENE, appena allargo il range PAGINA BIANCA, per eseguire lo script ci vuole troppo tempo (più di 30 sec)

SOLUZIONI ?

Sono in mano a voi.
 
Ultima modifica:

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
ciao,
a dir la verita ho capito poco il tuo codice

PHP:
<?php

$query = "SELECT e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,
                 
                 FROM 'TABELLA' WHERE giorno >= '$date1' AND giorno <= '$date2'";
$result = mysql_query($query);
//cambia nome variabile visto che poi usi la stessa per fare altro
$numero_righe = mysql_num_rows($result); // NUMERO DI RIGHE
//
//e fin qui ci siamo, va bene, poi :

// , MYSQL_NUM dovrebbe essere una costante? a che serve?

while ($row = mysql_fetch_array($result, MYSQL_NUM)) {

    // questa probabilmente la puoi togliere

    $query = "SELECT e1, e2 FROM 'ALTRA TABELLA'";
    $result1 = mysql_query($query);
    // mi fermo qui e ti faccio qualche domanda
    // exit();
    while ($row1 = mysql_fetch_array($result1, MYSQL_NUM)) {
        $numero1 = $row1[0];
        $numero2 = $row1[1];

        if (in_array($numero1, $row) && in_array($numero2, $row)) {
            $coppia[$numero1][$numero2] = $coppia[$numero1][$numero2] + 1;
        }
    }
    // manca una }
}
?>

Cosa contengono i campi e1 e e2?
perche li cerchi in un altra tabella?

penso sia sufficente scrivere
while ($row1 = mysql_fetch_array($result)) {

la query che fai nel ciclo while è da evitare

Sicuramente ci si puo arrivare in un altro modo
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
allora spiego meglio cosa devo fare perchè penso che mi sono talmente impappinato ormai che non ne esco + e che si possa arrivare alla soluzione anche in modo diverso.

Io ho 2 tabelle di numeri,
nella prima tabella ho e1 ed e2 che sono una coppia con relativo id chiaramente,
nella seconda ho e1,e1,e3..... che sono 20 numeri ed io devo cercare all'interno di questa tabella quante volte escono e1 ed e2 della prima in un arco temporale.

immagina :

1 3 6 7 9 10 13 24 25 26 30 32 33 34 56 78 79 81 84 89 (20 numeri) con una data
1 2 3 4 5 6 7 8 9 24 45 56 57 58 59 64 68 70 80 90 stessa o diversa data
.......................................
e voglio sapere le coppie che sono uscite e quante volte da una data all'altra.

perchè la seconda tabella praticamente contiene

1 2
1 3
1 4
1 5
etc ............

spero di essere stato chiaro stavolta...e cmq GRAZIEEEEE
 

Trogo

Utente Attivo
11 Gen 2008
370
0
0
43
Sanremo
Se non sbaglio di grosso con questa query dovresti risolvere il problema in un colpo solo:

Codice:
SELECT num1,num2, COUNT(*) AS totale FROM t1, t2
WHERE (
  t1.e1 = t2.num1 OR
  t1.e2 = t2.num1 OR
  t1.e3 = t2.num1 OR
  t1.e4 = t2.num1 OR
  t1.e5 = t2.num1 OR
  t1.e6 = t2.num1 OR
  t1.e7 = t2.num1 OR
  t1.e8 = t2.num1 OR
  t1.e9 = t2.num1 OR
  t1.e10 = t2.num1 OR
  t1.e11 = t2.num1 OR
  t1.e12 = t2.num1 OR
  t1.e13 = t2.num1 OR
  t1.e14 = t2.num1 OR
  t1.e15 = t2.num1 OR
  t1.e16 = t2.num1 OR
  t1.e17 = t2.num1 OR
  t1.e18 = t2.num1 OR
  t1.e19 = t2.num1 OR
  t1.e20 = t2.num1
) AND (
  t1.e1 = t2.num2 OR
  t1.e2 = t2.num2 OR
  t1.e3 = t2.num2 OR
  t1.e4 = t2.num2 OR
  t1.e5 = t2.num2 OR
  t1.e6 = t2.num2 OR
  t1.e7 = t2.num2 OR
  t1.e8 = t2.num2 OR
  t1.e9 = t2.num2 OR
  t1.e10 = t2.num2 OR
  t1.e11 = t2.num2 OR
  t1.e12 = t2.num2 OR
  t1.e13 = t2.num2 OR
  t1.e14 = t2.num2 OR
  t1.e15 = t2.num2 OR
  t1.e16 = t2.num2 OR
  t1.e17 = t2.num2 OR
  t1.e18 = t2.num2 OR
  t1.e19 = t2.num2 OR
  t1.e20 = t2.num2
) AND giorno >= '2000-01-01' AND giorno <= '2011-12-31'
GROUP BY CONCAT(num1,num2)

Prima di usarla meglio che fai qualche prova con un set di dati limitato per verificare i risultati
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
Se non sbaglio di grosso con questa query dovresti risolvere il problema in un colpo solo:

Codice:
SELECT num1,num2, COUNT(*) AS totale FROM t1, t2
WHERE (
  t1.e1 = t2.num1 OR
  t1.e2 = t2.num1 OR
  t1.e3 = t2.num1 OR
  t1.e4 = t2.num1 OR
  t1.e5 = t2.num1 OR
  t1.e6 = t2.num1 OR
  t1.e7 = t2.num1 OR
  t1.e8 = t2.num1 OR
  t1.e9 = t2.num1 OR
  t1.e10 = t2.num1 OR
  t1.e11 = t2.num1 OR
  t1.e12 = t2.num1 OR
  t1.e13 = t2.num1 OR
  t1.e14 = t2.num1 OR
  t1.e15 = t2.num1 OR
  t1.e16 = t2.num1 OR
  t1.e17 = t2.num1 OR
  t1.e18 = t2.num1 OR
  t1.e19 = t2.num1 OR
  t1.e20 = t2.num1
) AND (
  t1.e1 = t2.num2 OR
  t1.e2 = t2.num2 OR
  t1.e3 = t2.num2 OR
  t1.e4 = t2.num2 OR
  t1.e5 = t2.num2 OR
  t1.e6 = t2.num2 OR
  t1.e7 = t2.num2 OR
  t1.e8 = t2.num2 OR
  t1.e9 = t2.num2 OR
  t1.e10 = t2.num2 OR
  t1.e11 = t2.num2 OR
  t1.e12 = t2.num2 OR
  t1.e13 = t2.num2 OR
  t1.e14 = t2.num2 OR
  t1.e15 = t2.num2 OR
  t1.e16 = t2.num2 OR
  t1.e17 = t2.num2 OR
  t1.e18 = t2.num2 OR
  t1.e19 = t2.num2 OR
  t1.e20 = t2.num2
) AND giorno >= '2000-01-01' AND giorno <= '2011-12-31'
GROUP BY CONCAT(num1,num2)

Prima di usarla meglio che fai qualche prova con un set di dati limitato per verificare i risultati



Scusa ma num1 e num2 cambiano non sono sempre gli stessi, magari spiegami bene sta query grazie
 

Trogo

Utente Attivo
11 Gen 2008
370
0
0
43
Sanremo
Allora vediamo:

Codice:
SELECT num1,num2, COUNT(*) AS totale FROM t1, t2

Questa parte effettua una CROSS JOIN delle due tabelle (in pratica il prodotto cartesiano, cioè combina ogni riga di una tabella con ogni riga dell'altra tabella).
Quindi se la tabella t1 ha 200 record e la seconda 50 il risultato saranno 200 x 50 = 10000 record.

Quindi da questo risultato dobbiamo estrarre solo i record in cui t2.num1 E t2.num2 siano presenti nelle colonne di t1

Codice:
WHERE (
  t1.e1 = t2.num1 OR
  t1.e2 = t2.num1 OR
  t1.e3 = t2.num1 OR
  t1.e4 = t2.num1 OR
  t1.e5 = t2.num1 OR
  t1.e6 = t2.num1 OR
  t1.e7 = t2.num1 OR
  t1.e8 = t2.num1 OR
  t1.e9 = t2.num1 OR
  t1.e10 = t2.num1 OR
  t1.e11 = t2.num1 OR
  t1.e12 = t2.num1 OR
  t1.e13 = t2.num1 OR
  t1.e14 = t2.num1 OR
  t1.e15 = t2.num1 OR
  t1.e16 = t2.num1 OR
  t1.e17 = t2.num1 OR
  t1.e18 = t2.num1 OR
  t1.e19 = t2.num1 OR
  t1.e20 = t2.num1
) AND (
  t1.e1 = t2.num2 OR
  t1.e2 = t2.num2 OR
  t1.e3 = t2.num2 OR
  t1.e4 = t2.num2 OR
  t1.e5 = t2.num2 OR
  t1.e6 = t2.num2 OR
  t1.e7 = t2.num2 OR
  t1.e8 = t2.num2 OR
  t1.e9 = t2.num2 OR
  t1.e10 = t2.num2 OR
  t1.e11 = t2.num2 OR
  t1.e12 = t2.num2 OR
  t1.e13 = t2.num2 OR
  t1.e14 = t2.num2 OR
  t1.e15 = t2.num2 OR
  t1.e16 = t2.num2 OR
  t1.e17 = t2.num2 OR
  t1.e18 = t2.num2 OR
  t1.e19 = t2.num2 OR
  t1.e20 = t2.num2
)

Filtriamo ancora per limitare il range di date:

Codice:
AND giorno >= '2000-01-01' AND giorno <= '2011-12-31'

A questo punto abbiamo come risultato i record che ci interessano.

Adesso arriva l'ultima parte:

Codice:
GROUP BY num1,num2

GROUP BY permette di raggruppare i record in base ai campi specificati ( in realtà il CONCAT del post precedente non serve quindi l'ho tolto ). In pratica se due o più record hanno gli stessi valori di num1 e num2, vengono presi una sola volta. La comodità di questo è che così facendo il COUNT(*) all'inizio della query non conta più il totale dei record, ma i totali parziali di ogni raggruppamento.

Spero di essere riuscito a spiegarmi abbastanza bene
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ciao,
io proverei in questo modo sfruttando gli array:

PHP:
<?php

$conn = mysql_connect('localhost', 'root', '', 'database');
$db = mysql_select_db('database');

// estrai le coppie di numeri che vuoi cercare
$query = "SELECT e1,e2 FROM altratabella WHERE id IN(23,45,63,47,12,30)";
$res = mysql_query($query);

// crei un array con i risultati ottenuti
$coppieNumeri = array();
while ($row = mysql_fetch_array($res)) {
    $coppieNumeri[] = $row[0] . "," . $row[1];
}

// ricerca per data
$data1 = '2011-11-01';
$data2 = '2011-12-31';
$query = "SELECT * FROM tabella
                   WHERE data BETWEEN '$data1' AND DATE_ADD('$data2',INTERVAL 1 DAY)";
$res = mysql_query($query);
// crei un array con i risultati della ricerca per data
$arrayRisultati = array();
while ($row = mysql_fetch_array($res)) {
    $arrayRisultati[] = $row;
}

// cicli le coppie di numeri
foreach ($coppieNumeri as $value) {
    $ricorrenza = 0;
    // esplodi la stringa per ottenere i due numeri
    $coppia = explode(',', $value);
    // cicli l'array con i risultati della ricerca per data    
    foreach ($arrayRisultati as $value) {
        // verifichi se i numeri sono presenti nel risutltato
        if (in_array($coppia[0], $value) && in_array($coppia[1], $value)) {
            // li conti
            $ricorrenza++;
        }
    }
    // stampi il risultato
    echo $ricorrenza . " risultati per la coppia " . $coppia[0] . " e " . $coppia[1] . "<br/>";
}
?>
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
Ciao,
io proverei in questo modo sfruttando gli array:

PHP:
<?php

$conn = mysql_connect('localhost', 'root', '', 'database');
$db = mysql_select_db('database');

// estrai le coppie di numeri che vuoi cercare
$query = "SELECT e1,e2 FROM altratabella WHERE id IN(23,45,63,47,12,30)";
$res = mysql_query($query);

// crei un array con i risultati ottenuti
$coppieNumeri = array();
while ($row = mysql_fetch_array($res)) {
    $coppieNumeri[] = $row[0] . "," . $row[1];
}

// ricerca per data
$data1 = '2011-11-01';
$data2 = '2011-12-31';
$query = "SELECT * FROM tabella
                   WHERE data BETWEEN '$data1' AND DATE_ADD('$data2',INTERVAL 1 DAY)";
$res = mysql_query($query);
// crei un array con i risultati della ricerca per data
$arrayRisultati = array();
while ($row = mysql_fetch_array($res)) {
    $arrayRisultati[] = $row;
}

// cicli le coppie di numeri
foreach ($coppieNumeri as $value) {
    $ricorrenza = 0;
    // esplodi la stringa per ottenere i due numeri
    $coppia = explode(',', $value);
    // cicli l'array con i risultati della ricerca per data    
    foreach ($arrayRisultati as $value) {
        // verifichi se i numeri sono presenti nel risutltato
        if (in_array($coppia[0], $value) && in_array($coppia[1], $value)) {
            // li conti
            $ricorrenza++;
        }
    }
    // stampi il risultato
    echo $ricorrenza . " risultati per la coppia " . $coppia[0] . " e " . $coppia[1] . "<br/>";
}
?>


l'idea è proprio questa anche se tu l'hai strutturata diversamente da me, ma io ho quasi 5000 coppie da confrontare con 160000 righe su 20 colonne, non finisce mai di fare i cicli, ci mette troppo tempo....mi sa che sto cercando una soluzione impossibile.
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
Ok, ho dovuto risolvere diminuendo drasticamente il range di date, ma credo possa andare bene anche così.

Ulteriore problemino : ho aggiunto un altro campo alla tabella1 nella prima select :

$query = "SELECT id,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20 FROM TABELLA1 WHERE giorno >= '$date1' AND giorno <= '$date2'";

il campo in questione è il numero di ID.
Seguendo ciò che dice criric :

foreach ($arrayRisultati as $value) {
if (in_array($e1, $value) && in_array($e2, $value)) { // verifico se i numeri sono presenti nel risutltato
$coppia[$e1][$e2]++; // li conto
}
}

Ho ottenuto ciò che cercavo, ma ora vorrei anche sapere qual'è l'ultimo ID della coppia.
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ciao,

forse cosi:

foreach ($arrayRisultati as $key => $value) {

echo $key;
}

continuo col dire che secondo me BETWEEN è piu veloce di maggiore di... e minore di ...

poi magari la sparo grossa...
 

mephjl

Nuovo Utente
7 Mar 2012
9
0
0
Ciao,

forse cosi:

foreach ($arrayRisultati as $key => $value) {

echo $key;
}

continuo col dire che secondo me BETWEEN è piu veloce di maggiore di... e minore di ...

poi magari la sparo grossa...



eccolo :

foreach ($arrayRisultati as $key => $value) {
if (in_array($e1, $value) && in_array($e2, $value)) { // verifico se i numeri sono presenti nel risultato
$idestr[$e1][$e2] = $arrayRisultati[$key][0];
$ritatt[$e1][$e2] = ( $idlastestr - $idestr[$e1][$e2] );
$coppia[$e1][$e2]++; // li conto
}
}


Proverò il BETWEEN molto presto, dato che la query iniziale è solo di prova.

Un ultima cosa che non centra nulla con questo fin'ora esposto e credo sono apposto :

In una query faccio l'ORDER BY di una sola colonna e va tutto bene, ma se lo faccio di 2 il risultato non è quello sperato :

SELECT * FROM TABELLA ORDER BY campo1,campo2,campo3 DESC

ho provato anche col CONCAT, ma non li ordina bene.
 
Discussioni simili
Autore Titolo Forum Risposte Data
V [MySQL] problema query con date su server MySQL 5
G Mysql ( Query) problema interrogazione MySQL 0
G problema query mysql in php PHP 5
G Problema con query mysql MySQL 1
B problema query mysql php PHP 1
L PHP: problema con query mysql. PHP 3
S Autocompletamente con jQuery, PHP e MySQL - Problema con le query PHP 7
Boscagoo Problema query mySQL MySQL 6
K [MYSQL] problema con una query in loop MySQL 1
A problema: estrazione dati da query mysql e assegnazione ad una variabile PHP 2
B Problema con query mySql Java 2
A problema con query mysql PHP 1
O problema con query PHP 4
L problema con query select PHP 2
R Problema query con ricerca id numerico PHP 2
M Problema su query JOIN in tre tabelle PHP 0
G Problema ------- con Query PHP 1
G Problema con Query PHP 1
A [PHP] Problema query insert [RISOLTO] PHP 14
M [PHP] Problema con query select PHP 2
T [php] problema creazione query select-where PHP 5
trattorino problema raccapricciante php conteggio query PHP 4
L [PHP] Problema creazione query a numero di parametri variabile PHP 6
D Problema con query in php PHP 5
E [PHP] problema insert query PHP 9
M [PHP] Problema con query PHP 17
Rikk73 [C#] problema con stampa da query linq EnumerableRowCollection .NET Framework 0
M Problema con query PHP 15
G Problema con una query. PHP 5
F problema su query con nome tabella variabile PHP 20
F PHP problema doppi apici all'interno di una query SQL PHP 1
M problema con media query CSS HTML e CSS 1
D Problema caratteri jolle su criterio Query MS Access 0
L problema creazione query con campo float PHP 2
elpirata Query di ricerca problema campo data italiano PHP 2
andrea.peo Problema query con join visualizzazione record ripetuti PHP 5
X Problema di sostituzione tramite query sql MySQL 5
S Problema Query PHP 2
S Problema query PHP 25
Emix Problema query inserimento... PHP 6
B problema query PHP 6
Emix Dubbio e problema su query con operatore LIKE PHP 56
S Problema query con sum MySQL 4
A problema query e javascript Javascript 0
D E' natale lo so... ma ho un problema su una query :S MySQL 7
L query sqlite problema PHP 3
EffeElle Php problema query select PHP 5
Trapano Problema con query MySQL 32
EffeElle Problema per una query di aggiornamento record php PHP 35
V Problema query PHP 3

Discussioni simili