2017-09-08 3 views
1

SQLクエリを実行して、特定の場所がポリゴンで定義された管轄区域に該当するかどうかを確認するアプリケーションを開発中です。これらの管轄区域は四半期ごとに更新されます。つまり、私がチェックしている日付と照合する必要があります。私はmySQL関数MBRContainsを使用して、私が見ている管轄区域の絞り込みを行い、アプリケーションが特定の点がそれらのいずれかにあるかどうかを簡単に確認できるようにしています。今、私のクエリは次のようになります。評価の順序を変更してSQLクエリの実行時間を短縮する

SELECT DISTINCT t0.id FROM jurisdiction t0 
WHERE t0.beginDate <= '2017-08-05' AND t0.endDate >= '2017-08-05' 
AND MBRContains(t0.geometry,GeomFromText("POINT(48.0 -120.0)")); 

私はMBRContainsが日付をチェックするよりも高価な操作であることをかなり確信しているが、私は多くのSQLで働いていないと私は作る方法がわかりませんよ管轄区域は最初に日付でフィルタリングされ、次にMBRContainsに対してチェックされます。これどうやってするの?このクエリで同じ結果を達成しながら他にも最適化を行うことはできますか?

+0

入力ミスであるかどうかはわかりませんが、入力が間違っています。 1つは、日付フィールドは 'DATE'データ型でなければなりません。文字列の値に固執しても、その比較が実際に意味をなされるように文字列をフォーマットする必要があります('06 -08-2001 'の終了日は'05 -08-2017'の後にあります。 '04 -08-2020の開始日は'05 -08-2017 'の前です) – Uueerdo

+0

@Uueerdo日付とポイントは例です。私はそれが正しい日付で渡され、結果を正しくフィルタリングしていることを確認しました。それは単にクエリが長時間かかるということだけです。 – user3726962

+0

beginDate、endDate、およびgeometryでインデックスを使用すると、アクセスが高速化されます。 – hackela

答えて

2

(beginDate、endDate)にインデックスを追加します。両方のフィールドに1つのインデックスがあり、別々のインデックスではありません。

さらに、指定された日付が常に単一の日付である場合、条件の日付部分を'2017-08-05' BETWEEN t0.beginDate AND t0.endDateに変更するとさらに役立ちますが、おそらくそうではありません。

また、過去の同様の質問で、より簡単な境界チェックで条件を追加することを提案しましたが、これもインデックスの恩恵を受ける可能性があります。それらは通常、より大きなバウンディングボックスが使用される状況を含んでいました。擬似条件は、「境界ボックス内のどこにあり、境界領域内にあるか」のようになります。 「バウンディングボックス内」では、インデックスを使用して遠く離れたポイントを削除し、より複雑な「境界エリア内」がチェックされるポイントの数を減らします。

1

MBRContainsGeomFromTextの場合、決定的な関数であり、そのようにフラグが立てられていない場合は、そうすることが役立ちます。

確定的関数は、常に同じ入力で同じ値を返す関数です。 UPPER()は同じ入力に対して常に同じ出力を与えるため、確定的です。つまり、中間値が決して変更されないことが分かっている場合、オプティマイザはショートカットを作成できます。決定論的関数の詳細については

(今、私は周りに検索することを、私はものを、それらの機能は、データベースの一部として提供されていることを見ないあなたは、私は関数を呼び出すSQLをスピードアップする方法の例として答えを残しています)

+0

'DATE(col)'は確定的ですが、オプティマイザは 'WHERE DATE(col)= CURDATE()'に 'INDEX(col)'を使用しません。その他のショートカットもありません。それはパンツ。 (OK、 'CURDATE'は一度しか評価されません)。 –

1

あなたが行っているような範囲を確認することは、最適化がうまくいかないことです。あなたが得ることができる最高ののは、テーブルの半分をスキャンすることです。それは問題である。

あなたは効果的にスキャンで立ち往生しています。次に、WHEREのどの部分が最初に評価されるのかという疑問は、マイナーであることが分かります。これは、行をフェッチすると、WHERE句にある可能性のあるほとんどすべての関数よりもコストがかかります。

SPATIALのインデックスをgeometryに表示しましたか?そのかもしれない大幅に役立ちます。もしそうなら、この答えの残りの部分は疑問です。あなたは巨大なデータセットについて話している場合は、

WHERE x BETWEEN ... 
    AND y BETWEEN ... 

INDEX(x), 
INDEX(y) 

が(いや、INDEX(x,y)は、任意のより良い動作しません。)

:すでに述べた

として、「バウンディングボックスは、」良い最初の試みでありますmore complex solutionが必要になる場合があります。

関連する問題