Ich habe 10 Tabellen mit derselben Struktur außer Tabellenname.Mysql gespeicherte Prozedur ist 20 Mal langsamer als Standardabfrage
ich habe ein sp (Stored Procedure) wie folgt definiert:
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])
Ich bin den sp mit der folgenden Zeile Aufruf:
call mySP('test') //it executes in 6,836s
Dann öffnete ich ein neues Standard Abfragefenster. Ich habe nur die obige Abfrage kopiert. Dann @ param1 durch 'test' ersetzt.
Dies ist in 0,321 ausgeführt und ist etwa 20 mal schneller als die gespeicherte Prozedur.
Ich habe den Parameterwert wiederholt geändert, um zu verhindern, dass das Ergebnis zwischengespeichert wird. Aber das hat das Ergebnis nicht verändert. Der SP ist etwa 20 mal langsamer als die äquivalente Standardabfrage.
Bitte können Sie mir helfen, herauszufinden, warum das passiert?
Hat jemand auf ähnliche Probleme stoßen?
Ich benutze mySQL 5.0.51 auf Windows Server 2008 R2 64 Bit.
bearbeiten: Ich verwende Navicat für den Test.
Jede Idee wird für mich hilfreich sein.
EDIT1:
Ich habe gerade einige Test erfolgt nach Barmar Antwort.
Am endlich ich habe die sp wie unten mit einer nur einer Zeile geändert:
SELECT * FROM table1 WHERE [email protected] AND [email protected]
Dann zunächst ich die standart Abfrage ausgeführt
SELECT * FROM table1 WHERE col1='test' AND col2='test' //Executed in 0.020s
Nachdem ich das mein sp genannt:
CALL MySp('test','test') //Executed in 0.466s
So habe ich Where-Klausel vollständig geändert, aber nichts geändert. Und ich rief das sp vom mysql Befehlsfenster anstelle von navicat an. Es gab dasselbe Ergebnis. Ich bleibe immer noch dran.
meine sp ddl:
CREATE DEFINER = `myDbName`@`%`
PROCEDURE `MySP` (param1 VARCHAR(100), param2 VARCHAR(100))
BEGIN
SELECT * FROM table1 WHERE col1=param1 AND col2=param2
END
Und col1 und col2 indiziert kombiniert.
Sie könnten sagen, warum verwenden Sie nicht Standardabfrage dann? Mein Software-Design ist dafür nicht geeignet. Ich muss gespeicherte Prozedur verwenden. Dieses Problem ist mir sehr wichtig.
EDIT2:
Ich habe Informationen Abfrage Profil bekommen. Der große Unterschied liegt in der "Datenzeile senden" in den SP-Profilinformationen. Das Senden des Datenteils dauert% 99 der Ausführungszeit der Abfrage. Ich mache einen Test auf dem lokalen Datenbankserver. Ich verbinde keine Verbindung zum Remote-Computer.
SP Profil Informationen
Abfrage Profil Informationen
I wie unten Kraftindex-Anweisung versucht haben, in meinem sp. Aber das gleiche Ergebnis.
SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE [email protected] AND [email protected]
Ich habe SP wie unten geändert.
EXPLAIN SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=param1 AND col2=param2
Dies gab dieses Ergebnis:
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:NULL
key:NULL
key_len:NULL
ref:NULL
rows:292004
Extra:Using where
Dann habe ich die Abfrage unten ausgeführt.
EXPLAIN SELECT * FROM table1 WHERE col1='test' AND col2='test'
Ergebnis ist:
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
Ich FORCE INDEX-Anweisung in SP verwenden. Aber es besteht darauf, den Index nicht zu verwenden. Irgendeine Idee? Ich glaube, ich bin fast zu Ende :)
Es könnte sein, dass MySQL nach dem Ausführen des SP das Ergebnis zwischengespeichert hat, und dann, wenn Sie es außerhalb des SP ausführen, trifft es nur den Cache, anstatt es erneut auszuführen. –
Übrigens, warum 10 Tabellen mit der gleichen Struktur? Warum kombinieren Sie sie nicht in 1 Tabelle? –
Datenbank-Design ist aus meiner Hand Ich würde nie so ein Design machen :) zuerst führe ich die Abfrage mit anderen Parameter dann sofort rufe ich die SP mit dem gleichen Parameter. Ergebnis gleich. Es scheint, dass sp nicht das Ergebnis vom Cache genommen hat. – bselvan