procedimento armazenado mysql é mais lento 20 vezes do que a consulta padrão

Eu tenho 10 tabelas com a mesma estrutura, exceto o nome da tabela.

Eu tenho um sp (procedimento armazenado) definido da seguinte forma:

 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)

Eu estou chamando o sp com a seguinte linha:

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

Então eu abri uma nova janela de consulta padrão. Acabei de copiar a consulta acima. Em seguida, substituiu @ param1 por 'test'.

Isso executado em 0,321s e é cerca de 20 vezes mais rápido que o procedimento armazenado.

Eu alterei o valor do parâmetro repetidamente para evitar que o resultado seja armazenado em cache. Mas isso não mudou o resultado. O SP é cerca de 20 vezes mais lento que a consulta padrão equivalente.

Por favor, você pode me ajudar a descobrir por que isso está acontecendo?

Alguém encontrou problemas semelhantes?

Eu estou usando o mySQL 5.0.51 no windows server 2008 R2 64 bit.

edit: Estou usando o Navicat para teste.

Qualquer ideia será útil para mim.

EDIT1:

Acabei de fazer alguns testes de acordo com a resposta de Barmar.

Finalmente eu mudei o sp como abaixo com apenas uma linha:

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

Então, em primeiro lugar eu executei a consulta standart

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

Depois liguei para o meu sp:

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

Então eu mudei a cláusula where inteiramente, mas nada mudou. E eu chamei o sp da janela de comando do mysql em vez do navicat. Deu o mesmo resultado. Eu ainda estou preso nisso.

meu 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 são combinados indexados.

Você poderia dizer que por que você não usa a consulta standart então? Meu design de software não é adequado para isso. Eu devo usar o procedimento armazenado. Então esse problema é muito importante para mim.

EDIT2:

Eu obtive informações de perfil de consulta. A grande diferença é por causa do "envio de linha de dados" em Informações do Perfil do SP. O envio de parte de dados leva 99% do tempo de execução da consulta. Eu estou fazendo teste no servidor de banco de dados local. Eu não estou conectando do computador remoto.

Informações de perfil SP

Informações de perfil de consulta

Eu tentei declaração de índice de força como abaixo no meu sp. Mas mesmo resultado.

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

Eu mudei sp como abaixo.

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

Isso deu esse resultado:

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

Então eu executei a consulta abaixo.

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

Resultado é:

 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

Eu estou usando a instrução FORCE INDEX no SP. Mas insiste em não usar o índice. Qualquer ideia? Eu acho que estou perto do fim :)

questionAnswers(4)

yourAnswerToTheQuestion