PDA

View Full Version : [MySql] Enorme dubbio su query...domani devo consegnare...please help me :-/


Trigger2009
29-06-2009, 16:42
Ciao,
allora la situazione è la seguente: devo ottimizzare una query di questo tipo (facciamo subito l'esempio pratico):

Ho una tabella INSERZIONE fatta così:


INSERZIONE:
mysql> DESCRIBE INSERZIONE;
+-----------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-----------------------+------+-----+---------+----------------+
| Id_Oggetto | int(11) | NO | PRI | NULL | auto_increment |
| Titolo | varchar(60) | NO | MUL | NULL | |
| Descrizione | text | YES | | NULL | |
| Costo_Base | decimal(6,2) | YES | | NULL | |
| Compralo_Subito | decimal(6,2) | YES | | NULL | |
| Scadenza | datetime | YES | MUL | NULL | |
| Stato_Oggetto | enum('nuovo','usato') | YES | | NULL | |
| Id_Venditore | varchar(20) | NO | | NULL | |
| Id_Categoria | varchar(30) | NO | | NULL | |
+-----------------+-----------------------+------+-----+---------+----------------+


I cui campi Titolo ed Oggetto sono indicizzati

La mia professoressa dice che se ho una query del tipo questa:


SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Scadenza > '2009-05-27 01:28:00' AND Scadenza < '2009-05-27 01:28:05'
OR Titolo = 'Kommodor 64';


sarà lenta perchè MySql usa un solo indice per query (fà riferimento alla versione 5.0 di MySql) e se non può utilizzare nessun indice utilizza una full table scan.

Mentre se prendo la stessa query e la ristrutturo dividendola in 2 UNION:


SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Scadenza > '2009-05-27 01:28:00' AND Scadenza < '2009-05-27 01:28:05'
UNION
SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Titolo = 'Kommodor 64';


sarà molto più veloce perchè avrà la possibilità di usare un indice per ogni UNION.

Ho un db molto popolato...le ho provate entrambe e danno risultati praticamente identici...come mai? cosa c'è di sbagliato?

Vi prego è urgentissimo...devo terminare entro questa sera...

Grazie

Trigger2009
29-06-2009, 19:56
please...qualcuno che ci illumina? Sono le ultime ore buone per ricevere un'illuminazione...domani alle 11:00 consegno tuto e quel che è fatto è fatto e quel che non è fatto non è fatto :muro:

Mattyfog
29-06-2009, 19:59
un augurio niente di +... ;)
purtroppo non so aiutarti...

Rintrah84
29-06-2009, 22:14
un augurio niente di +... ;)
purtroppo non so aiutarti...

doh ci avevo sperato che qualcuno fosse passato ad illuminarmi...vabbè grazie dell'augurio....io glielo porto così...poi speriamo che il lavoro le vada bene... :D

Gimli[2BV!2B]
29-06-2009, 22:21
Hai buttato un occhio all'explain della query? (http://dev.mysql.com/doc/refman/5.0/en/explain.html)

RaouL_BennetH
29-06-2009, 22:21
Spero solo di darti uno spunto dato che non sono a livelli universitari con i db.

Quello che volevo dirti di provare era semplicemente:



SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Scadenza BETWEEN '2009-05-27 01:28:00' AND '2009-05-27 01:28:05'
UNION ALL
SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Titolo = 'Kommodor 64';



Non ho una mole di dati come la tua, non potrei neanche provare :)

Trigger2009
29-06-2009, 22:38
Spero solo di darti uno spunto dato che non sono a livelli universitari con i db.

Quello che volevo dirti di provare era semplicemente:



SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Scadenza BETWEEN '2009-05-27 01:28:00' AND '2009-05-27 01:28:05'
UNION ALL
SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
WHERE Titolo = 'Kommodor 64';



Non ho una mole di dati come la tua, non potrei neanche provare :)

Ci mette sempre circa lo stesso tempo...poi di volta in volta che lo rieseguo cambia...nel senso che credo dipenda anche da quante risorse mi succhiano gli altri programmi...comunque anche questa versione ci mette circa lo stesso tempo dell'altra...
Cosa dovrebbe cambiare la tua versione dalla mia? dire UNION non è come dire UNION ALL?

posto gli EXPLAIN delle due query, riuscite a dirmi se la forma finale è la stessa e a motivarmela in qualche modo?


QUERY ORIGINALE:

mysql> explain
-> SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
-> WHERE Scadenza > '2009-05-27 01:28:00' AND Scadenza < '2009-05-27 01:28:05'
-> OR Titolo = 'Kommodor 64'
-> \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: INSERZIONE
type: index_merge
possible_keys: Titolo,Scadenza_Index
key: Scadenza_Index,Titolo
key_len: 9,62
ref: NULL
rows: 4
Extra: Using sort_union(Scadenza_Index,Titolo); Using where
1 row in set (0.00 sec)

QUERY CHE USA LA UNION:

mysql> EXPLAIN
-> SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
-> WHERE Scadenza BETWEEN '2009-05-27 01:28:00' AND '2009-05-27 01:28:05'
-> UNION ALL
-> SELECT Id_Venditore, Titolo, Descrizione, Costo_Base FROM INSERZIONE
-> WHERE Titolo = 'Kommodor 64'\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: INSERZIONE
type: range
possible_keys: Scadenza_Index
key: Scadenza_Index
key_len: 9
ref: NULL
rows: 6
Extra: Using where
*************************** 2. row ***************************
id: 2
select_type: UNION
table: INSERZIONE
type: ref
possible_keys: Titolo
key: Titolo
key_len: 62
ref: const
rows: 2
Extra: Using where
*************************** 3. row ***************************
id: NULL
select_type: UNION RESULT
table: <union1,2>
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra:
3 rows in set (0.01 sec)


Grazie

Trigger2009
29-06-2009, 22:41
Dai ragazzi....illuminateci...io e Rintrah stiamo facendo questo progetto insieme...domani la proff lo controlla e dopomani esame orale...se non le va bene ci spella vivi a tutti e due :cry:

gugoXX
30-06-2009, 07:24
A differenza di cosa ha detto la professoressa, sembra proprio che invece MySql abbia operato una Merge di 2 indici. Nel piano di esecuzione puoi infatti leggere "index_merge", che ha svolto fondendo appunto insieme gli indici che avete messo sulle 2 colonne.

PS: Usa la BETWEEN sempre, in entrambe le scritture

Trigger2009
30-06-2009, 08:37
A differenza di cosa ha detto la professoressa, sembra proprio che invece MySql abbia operato una Merge di 2 indici. Nel piano di esecuzione puoi infatti leggere "index_merge", che ha svolto fondendo appunto insieme gli indici che avete messo sulle 2 colonne.

PS: Usa la BETWEEN sempre, in entrambe le scritture

Ok,
ora correggo e mando in stampa...grazie !!! LA BEETWEN per cosa?

Tnx

gugoXX
30-06-2009, 08:38
Ok,
ora correggo e mando in stampa...grazie !!! LA BEETWEN per cosa?

Tnx

WHERE Scadenza BETWEEN '2009-05-27 01:28:00' AND '2009-05-27 01:28:05'
anche nella prima query.

Trigger2009
30-06-2009, 08:54
WHERE Scadenza BETWEEN '2009-05-27 01:28:00' AND '2009-05-27 01:28:05'
anche nella prima query.

ok e a livello di prestazioni cambia qualcosa? perchè? come gli giustifico che èmeglio usar beetwen che specificare il range?

gugoXX
30-06-2009, 11:16
ok e a livello di prestazioni cambia qualcosa? perchè? come gli giustifico che èmeglio usar beetwen che specificare il range?

Cambia a livello di engine, che sara' piu' stimolato ad usare una INDEX RANGE SCAN.
Oppure comunque ad ottimizzare il filtro durante l'esecuzione.

Quindi indirettamente anche prestazioni.