0
explain 
SELECT
    ip_src,
    (SELECT country FROM ip_location WHERE ip_start between (134744072-500000) and (134744072) and ip_end > 134744072) country_src,
    ip_dst
FROM
    event e
WHERE 
    long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1

パーティションプルーニング作業中

explain
SELECT
    ip_src,
    (SELECT country FROM ip_location WHERE ip_start between (ip_src-500000) and (ip_src) and ip_end > ip_src) country_src,
    ip_dst
FROM
    event e
WHERE 
    long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1

パーティションプルーニングが機能しない

2 つのクエリがあり、ip_src 値は 134744072 です。

私の Ip_location テーブルは、ip_start 列の範囲で分割されています。最初のクエリを実行すると、パーティションのプルーニングが行われますが、2 番目のクエリではすべてのパーティションにアクセスします。

誰でも私に手がかりを教えてください、私は周りを見回していますが、何が起こっているのかまだわかりません、前にありがとう:)

4

1 に答える 1

0

実際のデータがテーブルから読み取られる前に、実行計画 (不要なパーティションを含む) を決定するオプティマイザーが実行されます。

最初のクエリは、サブクエリをip_start定数値134744072-500000との間の特定の範囲に制限する134744072ため、データがどのパーティションにあるかが明確になります (ちなみに、サブクエリが最大 1 行を返すようにする必要があります。そうしないと、次のようになります。エラー)。

2 番目のクエリでは、オプティマイザは開始前に必要な範囲を知ることができません。テーブルを読み取るときに検出したデータに依存しeventます。select_typeこれが、このクエリの が であるdependent subqueryのに対し、最初のクエリのがである理由です (つまり、テーブルsubqueryから独立した固定の結果セット)。eventそのため、オプティマイザーはまだパーティションを除外できないため、すべてをリストします。クエリが実行されると、最初の行が読み取られ、 の値が であること、ip_srcつまり134744072-rangeip_startとデータが含まれるパーティションが認識されるため、MySQL は正しいパーティションでそれを検索します。

両方のクエリは実際にはその 1 つのパーティションからのみ読み取りますが、最初のクエリの場合、MySQL は開始前にそれを認識し、2 つ目のクエリは認識しません。

最後に警告: クエリを高速化するためにパーティションを使用しようとしているようです。これは、パーティションが使用されるものではありません! そのためにインデックスが使用されます。の場合limit 1、違いはありませんが、より多くの行をクエリすると、各パーティションは独立したテーブルのように機能します (基本的にはそうです)。いつインデックスがあるかは問題ではありません)、MySQL は 30、40 の異なるパーティション (= テーブル) でデータを検索する必要があり、すべてが独自のインデックス、ファイル、および構造を持っています。これは通常、パーティションを使用しない場合よりも遅くなります (そして、ほとんど速くなりません)。少なくとも 600k 行で、少なくともその影響を確認するには十分である可能性があるため、パーティショニングなしでテストを行ってください。

于 2016-11-01T22:20:21.210 に答える