Ho 10 tabelle con la stessa struttura eccetto il nome della tabella.La stored procedure mysql è più lenta 20 volte rispetto alla query standard
ho una sp (stored procedure) definito come segue:
select * from table1 where (@param1 IS NULL OR [email protected])
UNION ALL
select * from table2 where (@param1 IS NULL OR [email protected])
UNION ALL
...
...
UNION ALL
select * from table10 where (@param1 IS NULL OR [email protected])
che io chiamo la SP con la seguente riga:
call mySP('test') //it executes in 6,836s
Poi ho aperto una nuova finestra di query standard. Ho appena copiato la query sopra. Quindi sostituito @ param1 con 'test'.
Questo eseguito in 0,321s ed è circa 20 volte più veloce della stored procedure.
Ho modificato ripetutamente il valore del parametro per impedire che il risultato sia memorizzato nella cache. Ma questo non ha cambiato il risultato. L'SP è circa 20 volte più lento della query standard equivalente.
Per favore, puoi aiutarmi a capire perché questo sta accadendo?
Qualcuno ha riscontrato problemi simili?
Sto usando mySQL 5.0.51 su Windows Server 2008 R2 64 bit.
modifica: sto utilizzando Navicat per il test.
Qualsiasi idea sarà utile per me.
Edit1:
Ho solo fatto qualche prova secondo la risposta di Barmar.
Al infine ho cambiato sp simili sottostante con una sola fila:
SELECT * FROM table1 WHERE [email protected] AND [email protected]
Poi innanzi tutto eseguita la query standart
SELECT * FROM table1 WHERE col1='test' AND col2='test' //Executed in 0.020s
Dopo ho chiamato il mio sp:
CALL MySp('test','test') //Executed in 0.466s
Quindi ho cambiato completamente la clausola, ma nulla è cambiato. E ho chiamato la sp dalla finestra di comando mysql invece di navicat. Ha dato lo stesso risultato. Sono ancora bloccato su di esso.
mia sp DDL:
CREATE DEFINER = `myDbName`@`%`
PROCEDURE `MySP` (param1 VARCHAR(100), param2 VARCHAR(100))
BEGIN
SELECT * FROM table1 WHERE col1=param1 AND col2=param2
END
E col1 e col2 è combinati indicizzati.
Si potrebbe dire che non usi la query standard? Il mio software design non è adatto a questo. Devo usare la stored procedure. Quindi questo problema è molto importante per me.
Edit2:
ho ottenuto di query informazioni del profilo. La grande differenza è dovuta alla "trasmissione della riga di dati" in SP Profile Information. L'invio di parte dati richiede% 99 del tempo di esecuzione della query. Sto facendo test sul server di database locale. Non mi sto connettendo dal computer remoto.
Informazioni SP Profilo
Informazioni Query Profilo
ho cercato INDEX forza come qui di seguito nella mia sp. Ma lo stesso risultato.
SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE [email protected] AND [email protected]
Ho cambiato sp come di seguito.
EXPLAIN SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=param1 AND col2=param2
Questo ha dato questo risultato:
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:NULL
key:NULL
key_len:NULL
ref:NULL
rows:292004
Extra:Using where
allora ho eseguito la query di seguito.
EXPLAIN SELECT * FROM table1 WHERE col1='test' AND col2='test'
risultato è:
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:col1_co2_combined_index
key:col1_co2_combined_index
key_len:76
ref:const,const
rows:292004
Extra:Using where
Sto usando dichiarazione Force Index in SP. Ma insiste nel non usare l'indice. Qualche idea? Penso di essere vicino alla fine :)
Potrebbe essere che dopo aver eseguito l'SP, MySQL abbia memorizzato il risultato nella cache, e quindi quando lo si esegue all'esterno dell'SP, sta semplicemente colpendo la cache anziché eseguirla di nuovo. –
A proposito, perché 10 tavoli con la stessa struttura? Perché non combinarli in 1 tavolo? –
la progettazione del database è fuori mano non farei mai una tale progettazione :) prima eseguo la query con parametri diversi quindi immediatamente chiamo lo sp con lo stesso parametro. risultato uguale. sembra che SP non abbia nemmeno preso il risultato dalla cache. – bselvan