2017-05-25 10 views
0

MySQLデータベースに2つのテーブルがあります。一つのテーブルには、データロギングのためのものであり、次の列があります。クエリのパフォーマンスをさらに向上させることができます(MySQL)

(これは、データロガーテーブルと呼ばれてみましょう)

ID - プライマリキー

サイトID、機器ID、機器番号、機器パラメータ、値を、ログされた日付

この表のレコードを選択するには、サイトのid、装置ID、装置番号、装置パラメータがwhere句で使用され、日付範囲(ログされた日付)が指定されます。

他のテーブルには、(これはloggerparameterdetailsテーブルと呼ばれるとする)次の列があります

機器ID 機器パラメータ - これら2複合主キー

パラメータの説明とパラメータユニットは、他されていますこの表の列

データロガー表には多数のレコードがあります(年間レコード数は約100万レコードになります)。アプリケーションのレポート目的では、パラメータ名のloggerparameterdetailsテーブルを使用してデータロガーテーブルを結合し、where句にサイトID、機器番号、パラメータ名、日付の記録範囲を指定します。

だから私は2つのテーブルに対して次のインデックス作成:サイトID、機器ID、機器番号、パラメータの名前と日付ログイン含む

複合インデックス - (これらの列がWHERE句がそう作成した場所に来るデータロガーテーブルをこれらのインデックス)

パラメータ名 - loggerparameterdetailsテーブル(このカラムは今年の日付範囲について参加)

で使用されているので、私は、クエリをプロファイリングし、データ送信プロセスは約3.5〜4秒を示していることがわかり。

select logtbl.date_logged, logparam.cmd_desc, logtbl.value, logparam.cmd_unit 
from datalogger logtbl join loggerparameterdetails logparam 
on logtbl.cmd_name=logparam.cmd_name where logtbl.site_id=1 
and logtbl.equipment_number=1 and logtbl.cmd_name='aaaabbab' 
and logtbl.date_logged between '2016-02-02 00:00:00' and '2017-02-06 00:00:00' 

この時期はさらに大幅に改善することができます:クエリは次のようになりますか?

更新:

クエリの実行計画は以下の通りである:

'ID'; 'SELECT_TYPE'; 'テーブル'; 'タイプ'; 'possible_keys'; 'キー'; 'key_lenに';'; ';'; ';' ''; ''; '' ''; '' ''; '' '' '' '' ''; '使用する場所'

'1'; '単純'; 'logtbl'; '範囲'; 'loggertbl_combined_idx'; 'loggertbl_combined_idx'; '69'; \ N; '528604';結合バッファを使用する '

+1

また、あなたの質問を説明書とともに編集してください。 – Mihai

+0

あなたのクエリの前に 'explain'を追加し、その結果を投稿に追加してください。 – Alexey

+0

'SHOW CREATE TABLE'を提供すると、それほど混乱がなく正確です。 –

答えて

1

TL; DR;ので、多分私はすべてのその言い回しで有用な何かを逃した..とにかく

、上の複合インデックス

...

site_id 
equipment_number 
cmd_name 
date_logged 

...最も望ましいと思われる - などcmd_nameのインデックスに他のテーブル。

あなたは、MySQL Workbenchでこのクエリを実行する最も効率的な

+1

logtblの複合インデックスは、日付が最後である限り、任意の順序で指定できます。 –

+0

@rickjamesはカーディナリティを変えますか? – Strawberry

+0

流行の神話です。マルチカラムインデックスでは、カーディナリティは重要ではありません。悲しいかな、私は、BTreeがどのように働いているかを考えて思考を行使することを示唆する以外に、私の主張には「証拠」がありません。範囲の後のインデックスの部分がフィルタリングに使用されないため、日付(鳴っているものとして使用)は最後にする必要があります。 –

0

である確認するために、複合インデックスの順序を並べ替えるみてください。

EXPLAIN select logtbl.date_logged, logparam.cmd_desc, logtbl.value, logparam.cmd_unit 
from datalogger logtbl join loggerparameterdetails logparam 
on logtbl.cmd_name=logparam.cmd_name where logtbl.site_id=1 
and logtbl.equipment_number=1 and logtbl.cmd_name='aaaabbab' 
and logtbl.date_logged between '2016-02-02 00:00:00' and '2017-02-06 00:00:00' 

これは、索引を調整するのに役立ちます。テーブルスキャンがある場合は、複雑なインデックスに列が間違った順序で含まれている可能性があります。それにかかわらず、EXPLAINはさらなる改善が可能かどうかを教えてくれます。

関連する問題