2016-10-12 43 views
2

私は2つのパーティションを持つテーブルを持っています。パーティションはpactive = 1pinactive = 0です。私は、2つのパーティションがそれほど多くの利益を上げるわけではないことを理解していますが、これを使って1つのパーティションで切り詰めてロードし、別のパーティションにプレーンな挿入を行いました。MySQLのパーティションテーブルのインデックス

インデックスを作成するときに問題が発生します。

クエリは、このよう

select partitionflag,companyid,activityname 
from customformattributes 
where companyid=47 
     and activityname = 'Activity 1' 
     and partitionflag=0 

作成したインデックス行く -

create index idx_try on customformattributes(partitionflag,companyid,activityname,completiondate,attributename,isclosed) 

上記のクエリからretreivedされます周りの200000のレコードがあります。しかし、上記のインデックスと一緒にクエリを実行するには30秒以上かかります。そのような長い時間の理由は何ですか?また、上記のインデックスからpartitionflagを削除すると、インデックスは使用されません。

そして

  1. でもパーティションを利用可能で、オプティマイザは、インデックス定義で述べた必要なパーティションを持っている必要がありますように、それが唯一の正しい----必要なパーティションを打つ、理解はありますか?

これを理解する上の任意のアイデアは、あなたがそれで列を並べ替えることで、あなたのインデックスを最適化することができ、非常に有用

+0

説明出力がなければ、推測するだけで済みます。 – Shadow

+0

こんにちは、計画の詳細の下に見つけてください ID - 1 SELECT_TYPE - SIMPLE テーブル - customformattributes タイプ - REF possible_keys - idx_try キー - idx_try key_lenに - 213 REF - constの、constの、constの 行 - 247892 フィルター済み - 100.00 余分 - ここでは;インデックスを使用する –

+0

私は、クエリ実行計画に特に問題がないとは思わない。あなたは大きな結果を持っています。結果セットを減らし、クエリのパフォーマンスをそのようにチェックしようとしましたか? – Shadow

答えて

0

だろう。通常、索引の列は、カーディナリティーによって並べ替えられます(最高から順に、最低位まで)。カーディナリティは、指定した列のデータの一意性です。ですから、あなたのケースでは、customformattributesテーブルにcompanyidのバリエーションがたくさんあり、partitionflagのカーディナリティは2です(この列のオプションはすべて1と0です)。 クエリはまず、partitionflag = 0のすべての行をフィルタリングし、次に企業IDなどでフィルタリングします。 インデックスからpartitionflagを削除すると、インデックスを使用する代わりにフルテーブルスキャンを行う方がオプティマイザが決定する可能性があるため、クエリはインデックスを使用しませんでした(オプティマイザが適切な場合のほとんどの場合)

特定のクエリに対して

:以下、インデックスがかもしれ

select partitionflag,companyid,activityname 
from customformattributes 
where companyid=47 
    and activityname = 'Activity 1' 
    and partitionflag=0 

が良くなる(もちろんのでしょう:以下のルールが満たされなければならないインデックスを使用するクエリの場合

create index idx_try on customformattributes(companyid,activityname, completiondate,attributename, partitionflag, isclosed) 

- 左端の列をインデックス内のwhere句に存在する必要があります。また、使用するmysqlのバージョンによっては、追加のクエリ要件が必要になることがあります。たとえば、古いバージョンのmysqlを使用している場合、where句の列をインデックスにリストされているのと同じ順序で並べ替える必要があるかもしれません。 mysqlの最後のバージョンでは、クエリオプティマイザはwhere句の列を正しい順序で並べ替える責任があります。

SELECTクエリは、200k行を返し、インデックスが指定されたクエリに最適でない可能性があるため、30秒以上かかりました。パーティション化の2番目の質問については

:共通ルール列がなければなりませんので、あなたは、テーブル内のすべてのUNIQUEキーの一部でなければならないことで分割されている列が(主キーが定義上一意のキーでもあるということですPKにも追加されています)。テーブル構造とロジックで、テーブルのすべてのUNIQUEインデックスにパーティショニング列を追加できる場合は、テーブルを追加してテーブルを分割します。 パーティション分割が正しく行われると、分割プルーニングが有効になります。これは、SELECTクエリでは、指定されたデータが格納されているパーティション内のデータのみを検索します(そうでなければ、すべてのパーティションを検索します)。

ここでのパーティション分割: https://dev.mysql.com/doc/refman/5.6/en/partitioning-overview.html

+0

遅れた応答のお詫び。あなたの説明は私がインデックスをより良く理解するのを助けました..ありがとう!! –

+0

私はそれがあなたが質問の問題を解決するのを助けてくれることを祈っています。 – krasipenkov

+0

あなたは答えを受け入れることができますか? – krasipenkov

0

ディスクが遅いためクエリが遅くなります。

インデックスを設計するときにカーディナリティは重要ではありません。

そのクエリの最適な指標は、それがSELECTのどこに言及したすべての列が含まれているのでそれは「カバー」される

INDEX(companyid, activityname, partitionflag) -- in any order 

です。これはEXPLAINの「インデックスの使用」で示されます。

他の3列を省略すると、ディスクの読み込みが少なくて済みますので、クエリが高速になります。

クエリへいかなる変更を(など、ORDER BYを追加し、「>」に「=」からの変更を列を追加)を作成した場合、インデックスはもはや最適ではないかもしれません。

"また、上記のインデックスからパーティションフラグを削除すると、インデックスは使用されません。 - それはもはや「カバーしていない」ためです。

インデックスを使用する2つの方法があります。「カバーする」とデータをルックアップする方法です。 「カバリング」索引を持たない場合、オプティマイザは、索引の使用と索引とデータの間のバウンドを選択するのではなく、単に索引を無視して表をスキャンします。

+0

遅れた応答のお詫び。あなたの説明は私がインデックスをよりよく理解するのを助けました..ありがとう!! –

関連する問題