1

mysql クエリの結果セットの時系列のギャップを埋める必要があります。時系列のすべてのデータ ポイントを含むヘルパー テーブルを使用して外部結合を実行するオプションをテスト中です (このスレッドで示されているように: MySQL で日付のギャップを埋めるには? )。

私が直面している問題は、この結合を追加すると、クエリの応答時間が大幅に増加することです (サブ 1 秒から 90 秒になります)。

元のクエリは次のとおりです。

select date_format(fact_data7.date_collected,'%Y-%m') as date_col
   , date_format(fact_data7.date_collected,'%d-%H:%i:%s') as time_col
   , fact_data7.batch_id,fact_data7.value as fdvalue,entities.ticker as ticker
   , date_format(fact_data7.date_collected,'%Y-%m-%d') as date_col2
   , date_format(fact_data7.date_collected,'%Y') as year 
from fact_data7  
JOIN entities on fact_data7.entity_id=entities.id  
where (1=1)
  AND ((entities.id= 963
      AND fact_data7.metric_id=1
      ))
  AND date_format(fact_data7.date_collected,'%Y-%m') > '2008-01-01'
order by date_col asc

ヘルパー テーブル (month_fill) への外部結合を追加したクエリを次に示します。

select date_format(month_fill.date,'%Y-%m') as date_col
    , date_format(fact_data7.date_collected,'%d-%H:%i:%s') as time_col
    , fact_data7.batch_id,fact_data7.value as fdvalue
    , entities.ticker as ticker
    , date_format(fact_data7.date_collected,'%Y-%m-%d') as date_col2
    , date_format(fact_data7.date_collected,'%Y') as year 
from fact_data7
JOIN entities
  on fact_data7.entity_id=entities.id  
RIGHT OUTER JOIN month_fill
   on date_format(fact_data7.date_collected,'%Y-%m') =  date_format(month_fill.date,'%Y-%m')  
where (1=1)
  AND (
      (entities.id= 963 AND fact_data7.metric_id=1)
      OR (entities.id is null and fact_data7.metric_id is null)
      )
  AND date_format(month_fill.date,'%Y-%m') > '2008-01-01'
order by date_col asc

クエリを再構築してパフォーマンスを向上させることはできますか?探しているものを達成するための代替ソリューションはありますか?

11/15 更新:

最初のクエリの EXPLAIN 出力は次のとおりです。

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  entities    const   PRIMARY     PRIMARY     4   const   1   Using filesort
1   SIMPLE  fact_data7  ALL     NULL    NULL    NULL    NULL    230636  Using where

2 番目のクエリの EXPLAIN 出力は次のとおりです。

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  month_fill  index   NULL    date    8   NULL    204     Using where; Using index; Using temporary; Using filesort
1   SIMPLE  fact_data7  ALL     NULL    NULL    NULL    NULL    230636  Using where
1   SIMPLE  entities    eq_ref  PRIMARY     PRIMARY     4   findata.fact_data7.entity_id    1   Using where
4

2 に答える 2

0

whereを使わないように書き直してみる価値はあると思いますdate_format(date_collected)。このフィールドにインデックスがあると言いますが、使用されたことはありません (フィールドは関数の引数であり、MySQL は関数ベースのインデックスをサポートしていません)。

于 2011-11-15T13:37:33.570 に答える
0

クエリのリファクタリングを検討することさえせずに、日付列の fact_data7.data_collected と month_fill.date にインデックスを追加することから始めます。実行している範囲クエリ ">" はプロセスを遅くし、インデックスを追加すると理論的にはパフォーマンスが向上するはずですが、十分なレコードが必要です。そうしないと、インデックスの管理に関連する処理のためにインデックスの管理が遅くなるだけです。

このmysqlドキュメントを参照してくださいhttp://dev.mysql.com/doc/refman/5.0/en/optimization-indexes.html

何を達成しようとしているのか正確にはわかりませんがifnull(value1,value2)、mysql の機能を使用してそれを行うことができます。クエリは次のようになります。

select ifnull(date_format(fact_data7.date_collected,'%Y-%m'),date_format(month_fill.date,'%Y-%m')) as date_col, 
date_format(fact_data7.date_collected,'%d-%H:%i:%s') as time_col, 
fact_data7.batch_id,
fact_data7.value as fdvalue,
entities.ticker as ticker,
date_format(fact_data7.date_collected,'%Y-%m-%d') as date_col2 ,
date_format(fact_data7.date_collected,'%Y') as year 
from fact_data7 , month_fill
JOIN entities on fact_data7.entity_id=entities.id  
where ((entities.id= 963 AND fact_data7.metric_id=1) OR (entities.id is null and fact_data7.metric_id is null))
and date_format(fact_data7.date_collected,'%Y-%m') =  date_format(month_fill.date,'%Y-%m') --you will need a condition similar to this depends on the data
AND date_format(fact_data7.date_collected,'%Y-%m')>'2008-01-01'
order by date_col asc
于 2011-11-14T19:03:58.090 に答える