テーブル名を除いて同じ構造のテーブルが 10 個あります。
次のように定義されたsp(ストアドプロシージャ)があります:
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)
次の行でspを呼び出しています:
call mySP('test') //it executes in 6,836s
次に、新しい標準クエリ ウィンドウを開きました。上記のクエリをコピーしただけです。次に、@param1 を「test」に置き換えました。
これは 0,321 秒で実行され、ストアド プロシージャよりも約 20 倍高速です。
結果がキャッシュされないように、パラメーター値を繰り返し変更しました。しかし、これは結果を変えませんでした。SP は、同等の標準クエリよりも約 20 倍遅くなります。
なぜこれが起こっているのかを理解するのを手伝ってもらえますか?
誰かが同様の問題に遭遇しましたか?
Windows Server 2008 R2 64 ビットで mySQL 5.0.51 を使用しています。
編集: テストに Navicat を使用しています。
どんなアイデアも私にとって役に立ちます。
EDIT1:
Barmarの回答に従って、いくつかのテストを行ったところです。
最後に、以下のようにspを1行だけ変更しました:
SELECT * FROM table1 WHERE col1=@param1 AND col2=@param2
次に、最初に標準クエリを実行しました
SELECT * FROM table1 WHERE col1='test' AND col2='test' //Executed in 0.020s
私が私のSPを呼んだ後:
CALL MySp('test','test') //Executed in 0.466s
そのため、where句を完全に変更しましたが、何も変更されていません。そして、navicat の代わりに mysql コマンド ウィンドウから sp を呼び出しました。それは同じ結果をもたらしました。私はまだそれにこだわっています。
私のsp ddl:
CREATE DEFINER = `myDbName`@`%`
PROCEDURE `MySP` (param1 VARCHAR(100), param2 VARCHAR(100))
BEGIN
SELECT * FROM table1 WHERE col1=param1 AND col2=param2
END
また、col1 と col2 は結合されて索引付けされます。
では、なぜ標準クエリを使用しないのですか? 私のソフトウェア設計はこれには適していません。ストアド プロシージャを使用する必要があります。ですから、この問題は私にとって非常に重要です。
EDIT2:
クエリ プロファイル情報を取得しました。大きな違いは、SPプロファイル情報の「送信データ行」によるものです。データ部分の送信には、クエリ実行時間の %99 がかかります。ローカル データベース サーバーでテストを行っています。リモートコンピューターから接続していません。
SP プロファイル情報
プロファイル情報のクエリ
私は自分のspで以下のような強制インデックスステートメントを試しました. でも同じ結果。
SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=@param1 AND col2=@param2
以下のようにspを変更しました。
EXPLAIN SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=param1 AND col2=param2
これにより、次の結果が得られました。
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:NULL
key:NULL
key_len:NULL
ref:NULL
rows:292004
Extra:Using where
次に、以下のクエリを実行しました。
EXPLAIN SELECT * FROM table1 WHERE col1='test' AND col2='test'
結果は次のとおりです。
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
SP で FORCE INDEX ステートメントを使用しています。しかし、それはインデックスを使用しないことを主張しています。何か案が?私は終わりに近づいていると思います:)