2016-07-06 13 views
0

私はMySQLのエキスパートではありません。比較的複雑なクエリでは苦労しています。MySQL 5.6:グループ化されたパラメータを使用した複雑なクエリ

私は2つのテーブルがあります。次のように列を持つ

Aデータテーブルを:

`Location` bigint(20) unsigned NOT NULL, 
`Source` bigint(20) unsigned NOT NULL, 
`Param` bigint(20) unsigned NOT NULL, 
`Type` bigint(20) unsigned NOT NULL, 
`InitTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
`ValidTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
`Value` double DEFAULT NULL 
列を持つ

A場所グループテーブルを次のように

`Group` bigint(20) unsigned NOT NULL, 
`Location` bigint(20) unsigned NOT NULL, 

のデータテーブルのデータを格納します各「価値」は特定の「有効期間」に対して有効です。ただし、表のデータは定期的に実行される計算から得られます。計算が実行される初期化時間は、「inittime」フィールドに格納されます。特定のinittimeでの計算では、有効な時間(A〜J)で10個の値が出力されます。より最近のinittimeを使った最近の計算では、有効な時間(B〜K)で別の10個の値が出力される可能性があります。したがって、利用可能な値に重複があります。最新のinittime(つまりmax(inittime))の値とValidTimesの結果セットが常に必要です。

私は、次のクエリを使用して、最新inittimeを決定することができます。

SELECT MAX(InitTime) 
FROM Data 
WHERE 
    Location = 100060 AND 
    Source = 10 AND 
    Param = 1 AND 
    Type = 1; 

これは実行に0.072秒かかります。

ただし、これをサブクエリとして使用してデータテーブルからデータを取得すると、実行時間は45秒になります(非常に巨大なテーブルですが、非常にばかげていません)。

サブクエリ:

SELECT Location, ValidTime, Value 
FROM Data data 
WHERE Source = 10 
    AND Location IN (SELECT Location FROM Location Group WHERE Group = 3) 
    AND InitTime = (SELECT max(data2.InitTime) FROM Data data2 WHERE data.Location = data2.Location AND data.Source = data2.Source AND data.Param = data2.Param AND data.Type = data2.Type) 
ORDER BY Location, ValidTime ASC; 

(簡潔にするためにスニップValidTime予選)

私はここに役立つだろういくつかの最適化が可能性があります知っているが、私が開始する場所がわからないんだけど。代わりに、MAX(InitTime)クエリを効果的に実行するストアドプロシージャを作成しましたが、MAX(InitTime)はLocation、Source、Param、およびTypeのコンボで決まるため、特定の場所を含むすべての場所を渡す必要がありますグループ。簡単な方法が必要であることを認識する前に、このためのカーソルベースのストアドプロシージャを実装しました。

インデックスを使用して最適化の問題を別にすれば、特定のロケーショングループ、ソース、パラメータ、およびタイプの最新のInitTimeを使用して効率的にデータテーブルのクエリを実行できますか?

ありがとうございます!

答えて

0

MySQLはサブクエリ(ときどき)を使用してINを最適化するとジョブを最適化できません。また、索引が役立つ可能性があります。あなたはdata(Location, Source, Param, Type, InitTime)LocationGroup(Location, Group)、そしてdata(Source, Location, ValidTime)のインデックスをしたい、このクエリの

SELECT d.Location, d.ValidTime, d.Value 
FROM Data d 
WHERE d.Source = 10 AND 
     EXISTS (SELECT 1 FROM LocationGroup lg WHERE d.Location = lg.Location and lg.Group = 3) AND 
     d.InitTime = (SELECT max(d2.InitTime) 
        FROM Data d2 
        WHERE d.Location = d2.Location AND 
          d.Source = d2.Source AND 
          d.Param = d2.Param AND 
          d.Type = d2.Type 
        ) 
ORDER BY d.Location, d.ValidTime ASC; 

:だから、私は、クエリを記述します。

+0

お返事ありがとうございます。私はこれをテストするためにヒキガエルを使用しており、これを実装した後も同様の実行時間があります。しかし、結果ペインは、最後に1つの大きな塊ではなく定期的に更新されます。 – BeefyElbow

関連する問題