1

注:元の質問は意味がありませんが、関連するものを下までスキャンしてください。

次のような最適化したいクエリがあります。

select cols from tbl where col = "some run time value" limit 1;

どのキーが使用されているか知りたいのですが、説明するために渡すものは何でも、定数を入力したため、where句を最適化して何もできません(「不可能なWHEREに気づきました...」)。

  • Explain で一定の​​最適化を行わないように mysql に指示する方法はありますか?
  • 何か不足していますか?
  • 必要な情報を取得するためのより良い方法はありますか?

編集:EXPLAIN定数値から生じるクエリプランを私に与えているようです。クエリはストアド プロシージャの一部であるため (また、spoc 内の IIRC クエリ プランは呼び出される前に生成されます)、値が定数ではないため、これは役に立ちません。私が望むのは、オプティマイザが実際の値がわからないときに生成するクエリ プランを調べることです。

私は何かを逃していますか?

Edit2: 他の場所で尋ねると、MySQL は、再利用するためにわざわざ行かない限り、常にクエリ プランを再生成するようです。ストアド プロシージャでも。このことから、私の質問は無意味であるように思われます。

しかし、それは私が本当に知りたかったことを意味のあるものにしません. 特定のクエリ内で定数である値を含むクエリを最適化するにはどうすればよいですか? -- たとえば、クライアント側のコードがwhere句に数値を含むクエリを生成しているとします。数値が不可能な where 句になる場合もあれば、そうでない場合もあります。Explain を使用して、クエリがどの程度最適化されているかを調べるにはどうすればよいですか?

私がすぐに見ている最善のアプローチはEXPLAIN、存在する/存在しないケースの完全なマトリックスに対して実行することです。手動で行うのは難しく、エラーが発生しやすいため、実際にはあまり良い解決策ではありません。

4

3 に答える 3

5

指定した値が定数であるという理由だけでなく、列にないため、「不可能な WHERE 通知」が表示されます。1) 列に存在する値を使用するか、2) 次のように言うことができますcol = col

explain select cols from tbl where col = col;
于 2008-11-22T23:44:30.227 に答える
4

たとえば、クライアント側のコードが where 句に数値を含むクエリを生成しているとします。

数値が不可能な where 句になる場合もあれば、そうでない場合もあります。

Explain を使用して、クエリがどの程度最適化されているかを調べるにはどうすればよいですか?

MySQLバインドされたパラメーターのさまざまな値に対してさまざまなクエリ プランを作成します。

この記事では、オプティマイザーがいつMySQL何を行うかのリストを読むことができます。

    次の場合のアクション

    クエリ解析 PREPARE
    否定消去 PREPARE
    サブクエリは PREPARE を書き換えます

    入れ子になった JOIN の単純化 最初の EXECUTE
    OUTER->INNER JOIN 変換 最初の EXECUTE

    パーティションのプルーニング
    COUNT/MIN/MAX 消去ごとの EXECUTE
    定数部分式の削除 Every EXECUTE
    等値伝播の実行ごと
    定数テーブルの検出 EXECUTE ごと
    ref アクセス解析 Every EXECUTE
    range/index_merge 分析と最適化 すべての EXECUTE
    結合の最適化

このリストにはもう 1 つ欠けているものがあります。

MySQL反復ごとJOINにクエリ プランを再構築できますrange checking for each record

テーブルに複合インデックスがある場合:

CREATE INDEX ix_table2_col1_col2 ON table2 (col1, col2)

および次のようなクエリ:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col1 = t1.value1
        AND t2.col2 BETWEEN t1.value2_lowerbound AND t2.value2_upperbound

は、からへのインデックスアクセスをMySQL使用しません。代わりに、インデックスアクセスを使用して、間違った値を除外します。RANGE(t1.value1, t1.value2_lowerbound)(t1.value1, t1.value2_upperbound)REF(t1.value)

しかし、クエリを次のように書き直すと:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col1 <= t1.value1
        AND t2.col1 >= t2.value1
        AND t2.col2 BETWEEN t1.value2_lowerbound AND t2.value2_upperbound

からの各レコードのMySQLインデックスRANGEアクセスを再チェックし、その場でアクセスを使用するかどうかを決定します。table1RANGE

それについては、私のブログの次の記事で読むことができます。

これらすべてが採用しているRANGE CHECKING FOR EACH RECORD

質問に戻りますMySQL。定数が指定される前に計画がないため、指定された定数ごとにどの計画が使用されるかを知る方法はありません。

残念ながら、MySQLバインドされたパラメーターの値ごとに 1 つのクエリ プランを強制的に使用する方法はありません。

and句を使用して選択されるJOIN順序を制御できますが、インデックスに特定のアクセス パスを強制したり、.INDEXSTRAIGHT_JOINFORCE INDEXIMPOSSIBLE WHERE

一方、すべてJOINの の場合、MySQLのみを使用しNESTED LOOPSます。つまり、正しいJOIN順序を構築したり、正しいインデックスを選択したりすると、MySQLおそらく all の恩恵を受けるでしょうIMPOSSIBLE WHERE

于 2009-05-04T20:23:18.900 に答える