2016-10-06 3 views
0

私は最適化しようとしているMySQLのクエリを持っています。私は数十万行のテーブルtを持っていて、varcharカラムx(および他のもの)はインデックスが付けられていて、1000個未満の異なる値を持っています。私は特定の正規表現に一致するすべての別個のxを取得しようとしています。これは、これを策定する単純な方法である:正規表現クエリを最適化する

SELECT DISTINCT x 
FROM t 
WHERE x REGEXP 'someregexp' 

しかし、REGEXPを使用した場合、MySQLは完全にインデックスを無視のように思えるので、それは数秒かかります。私はかなり低い数の固有値を持っているので、インデックスを使って別の値を取得し、その結果を正規表現を使ってフィルタリングするなら、これを処理するのはかなり速いはずですが、今のようには見えませんなぜなら、1秒未満で実行できるはずだからです。

MySQLクエリオプティマイザにそのようにすることができる方法はありますか?それだけで行わなければならない場合、高速で正規表現を(

SELECT d.x 
FROM (SELECT DISTINCT x FROM t) d 
WHERE d.x REGEXP 'someregexp' 

それは最初の(インデックスに速いです)明確なフィルタリングを行う必要があり、この方法で、その後の操作を行います。

+0

が「インデックスが作成され」 - 'SHOW CREATE TABLE'を提供してください。 –

答えて

0

たぶん、このような何かを試してみてくださいいくつかの異なる値)。

0

プランA:

SELECT x 
    FROM t 
    GROUP BY x 
    HAVING x REGEXP 'someregexp'; 

(これは、サブクエリのアプローチがするように、書き込み、および読み込み、一時テーブルにする必要はありません。)

プランB:INDEX(x)を追加し、インデックスを飛び越えることができるように、新しいバージョンのMySQLを用意してください。 (MRR、おそらく5.6.10を参照してください)注:これはサブクエリのアプローチにも役立ちます。

プランC: MySQLのサポートは、マテリアライズド・ビューをも私は彼らがあなたのテーブルへの変更を遅らせるかもしれない恐怖と、これは可能だろうか「歓迎」場合はプランAとプランBの

0

両方が私にはわからないでください劇的に(**)。しかし、私は、サマリー表を維持する2つのトリガーと組み合わせた後の別個の値を保持するサマリー表を手に入れることができると思います。 (INSERTの場合は、サマリーテーブルにないものを追加するだけです)、DELETEでは、最後のテーブルを削除したかどうかをチェックし、サマリーテーブルから削除する場合はチェックする必要があります。両方を確認する必要があります)。

あなたがすでに持っているインデックスを考えると、これは面倒なIMHOであってはいけません。そのサマリーテーブルに約1000個の値しかないので、regexpももっと速くなると思います。

は(**:に大きく依存し、このことは、あなたの「ビュー」は完全にベーステーブルを変更するたびに更新された場合、その後、私は疑う、これは許容されるものであるか、「スマート」)