Procedura przechowywana mysql jest wolniejsza 20 razy niż standardowe zapytanie

Mam 10 stołów o tej samej strukturze z wyjątkiem nazwy tabeli.

Mam sp (procedurę przechowywaną) zdefiniowaną następująco:

 select * from table1 where (@param1 IS NULL OR col1=@param1)
 UNION ALL
 select * from table2 where (@param1 IS NULL OR col1=@param1)
 UNION ALL
 ...
 ...
 UNION ALL
 select * from table10 where (@param1 IS NULL OR col1=@param1)

Nazywam sp z następującej linii:

call mySP('test')  //it executes in 6,836s

Następnie otworzyłem nowe standardowe okno zapytania. Właśnie skopiowałem powyższe zapytanie. Następnie zastąpiono @ param1 słowem „test”.

Wykonano to w 0,321s i jest około 20 razy szybsze niż procedura składowana.

Wielokrotnie zmieniłem wartość parametru, aby zapobiec buforowaniu wyniku. Ale to nie zmieniło wyniku. SP jest około 20 razy wolniejsza niż równoważne standardowe zapytanie.

Czy możesz mi pomóc dowiedzieć się, dlaczego tak się dzieje?

Czy ktoś napotkał podobne problemy?

Używam mySQL 5.0.51 na Windows Server 2008 R2 64-bit.

edit: używam Navicat do testowania.

Każdy pomysł będzie dla mnie pomocny.

EDIT1:

Po prostu wykonałem test zgodnie z odpowiedzią Barmara.

W końcu zmieniłem sp jak poniżej z jednym tylko jednym wierszem:

 SELECT * FROM table1 WHERE col1=@param1 AND col2=@param2

Następnie najpierw wykonałem zapytanie standartowe

 SELECT * FROM table1 WHERE col1='test' AND col2='test'  //Executed in 0.020s

Po wywołaniu my sp:

 CALL MySp('test','test')    //Executed in 0.466s

Zmieniłem więc całkowicie klauzulę, ale nic się nie zmieniło. I wywołałem sp z okna poleceń mysql zamiast navicat. Dało to taki sam rezultat. Nadal na tym utknąłem.

mój spddl:

 CREATE DEFINER = `myDbName`@`%`
 PROCEDURE `MySP` (param1 VARCHAR(100), param2 VARCHAR(100))
 BEGIN
    SELECT * FROM table1 WHERE col1=param1 AND col2=param2
 END

A col1 i col2 są połączone indeksowane.

Można powiedzieć, że dlaczego nie używasz wtedy standardowego zapytania? Mój projekt oprogramowania nie jest do tego odpowiedni. Muszę użyć procedury przechowywanej. Więc ten problem jest dla mnie bardzo ważny.

EDIT2:

Otrzymałem informacje o profilu zapytania. Duża różnica polega na „wysyłaniu wiersza danych” w informacji profilu SP. Część danych wysyłanych zajmuje% 99 czasu wykonania zapytania. Robię test na lokalnym serwerze bazy danych. Nie łączę się z komputerem zdalnym.

Informacje profilu SP

Informacje o profilu zapytania

Próbowałem wymusić wypowiedź indeksu jak poniżej w moim sp. Ale ten sam wynik.

 SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=@param1 AND col2=@param2

Zmieniłem sp jak poniżej.

 EXPLAIN SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=param1 AND col2=param2

Dało to ten wynik:

 id:1
 select_type=SIMPLE
 table:table1
 type=ref
 possible_keys:NULL
 key:NULL
 key_len:NULL
 ref:NULL
 rows:292004
 Extra:Using where

Następnie wykonałem zapytanie poniżej.

 EXPLAIN SELECT * FROM table1 WHERE col1='test' AND col2='test'

Wynik:

 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

Używam instrukcji FORCE INDEX w SP. Ale nalega na nieużywanie indeksu. Dowolny pomysł? Myślę, że jestem blisko końca :)

questionAnswers(4)

yourAnswerToTheQuestion