Iは、以下のスキーマで3つのテーブルを有する:MAXとMySQLのクエリ最適化()
CREATE TABLE `devices` (
`device_id` int(11) NOT NULL auto_increment,
`name` varchar(20) default NULL,
`appliance_id` int(11) default '0',
`sensor_type` int(11) default '0',
`display_name` VARCHAR(100),
PRIMARY KEY USING BTREE (`device_id`)
)
CREATE TABLE `channels` (
`channel_id` int(11) NOT NULL AUTO_INCREMENT,
`device_id` int(11) NOT NULL,
`channel` varchar(10) NOT NULL,
PRIMARY KEY (`channel_id`),
KEY `device_id_idx` (`device_id`)
)
CREATE TABLE `historical_data` (
`date_time` datetime NOT NULL,
`channel_id` int(11) NOT NULL,
`data` float DEFAULT NULL,
`unit` varchar(10) DEFAULT NULL,
KEY `devices_datetime_idx` (`date_time`) USING BTREE,
KEY `channel_id_idx` (`channel_id`)
)
設定は、デバイスが1つまたは複数のチャネルを有することができることであり、各チャネルは、多くの(過去の)データを有しています。
私は1つのデバイスと、それがチャンネルを関連だすべての最後の履歴データを取得するには、次のクエリを使用:
SELECT c.channel_id, c.channel, max(h.date_time), h.data
FROM devices d
INNER JOIN channels c ON c.device_id = d.device_id
INNER JOIN historical_data h ON h.channel_id = c.channel_id
WHERE d.name = 'livingroom' AND d.appliance_id = '0'
AND d.sensor_type = 1 AND (c.channel = 'ch1')
GROUP BY c.channel
ORDER BY h.date_time, channel
次のようにクエリプランが見えます:
+----+-------------+-------+--------+-----------------------+----------------+---------+---------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-----------------------+----------------+---------+---------------------------+--------+-------------+
| 1 | SIMPLE | c | ALL | PRIMARY,device_id_idx | NULL | NULL | NULL | 34 | Using where |
| 1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 4 | c.device_id | 1 | Using where |
| 1 | SIMPLE | h | ref | channel_id_idx | channel_id_idx | 4 | c.channel_id | 322019 | |
+----+-------------+-------+--------+-----------------------+----------------+---------+---------------------------+--------+-------------+
3 rows in set (0.00 sec)
上記のクエリは、現在あります約15秒かかりました。質問を改善するためのヒントや方法があるかどうかを知りたがっていますか?
編集:HISTORICAL_DATAから 例データ
+---------------------+------------+------+------+
| date_time | channel_id | data | unit |
+---------------------+------------+------+------+
| 2011-11-20 21:30:57 | 34 | 23.5 | C |
| 2011-11-20 21:30:57 | 9 | 68 | W |
| 2011-11-20 21:30:54 | 34 | 23.5 | C |
| 2011-11-20 21:30:54 | 5 | 316 | W |
| 2011-11-20 21:30:53 | 34 | 23.5 | C |
| 2011-11-20 21:30:53 | 2 | 34 | W |
| 2011-11-20 21:30:51 | 34 | 23.4 | C |
| 2011-11-20 21:30:51 | 9 | 68 | W |
| 2011-11-20 21:30:49 | 34 | 23.4 | C |
| 2011-11-20 21:30:49 | 4 | 193 | W |
+---------------------+------------+------+------+
10 rows in set (0.00 sec)
編集2: Mutlipleチャネル例SELECT:
SELECT c.channel_id, c.channel, max(h.date_time), h.data
FROM devices d
INNER JOIN channels c ON c.device_id = d.device_id
INNER JOIN historical_data h ON h.channel_id = c.channel_id
WHERE d.name = 'livingroom' AND d.appliance_id = '0'
AND d.sensor_type = 1 AND (c.channel = 'ch1' OR c.channel = 'ch2' OR c.channel = 'ch2')
GROUP BY c.channel
ORDER BY h.date_time, channel
私が使用したのか、簡単に句だったのでc.channelで文法的にプロを生成することができますが、必要に応じてINを使用するように変更できます。
編集3:私が達成しようとしているものの 例の結果は:
+-----------+------------+---------+---------------------+-------+
| device_id | channel_id | channel | max(h.date_time) | data |
+-----------+------------+---------+---------------------+-------+
| 28 | 9 | ch1 | 2011-11-21 20:39:36 | 0 |
| 28 | 35 | ch2 | 2011-11-21 20:30:55 | 32767 |
+-----------+------------+---------+---------------------+-------+
私が例にDEVICE_IDを追加したが、私の選択はCHANNEL_ID、チャネル、最後DATE_TIMEすなわち最大を返す必要がありますとデータ。結果は、1つのデバイスの各チャネルのhistorical_dataテーブルの最後のレコードになります。
トピック:グループ:c.channel_id、c.chann el、h.data – danihp
「最後の履歴データ」の意味をさらに説明できますか?これらのテーブルのサイズをランク付けできますか?最大のものは?クエリの変更を提案する前に、まずこれらのいくつかのことを知っておくと良いでしょう。次に、サンプルデータを提供できますか?私はあなたが 'max(h.date_time)'だけを取得しているときに 'h.data'の必要性について疑問に思っています。あなたは大量の情報を提供してくれました。ちょっとだけ!ありがとう! :) – Nonym
historical_dataテーブルにはセンサからの読み取り値が含まれており、現在300,000以上の行があります。 channelsテーブルには19個のレコードとデバイスがあります。特定のデバイスのhistory_dataテーブルでdatetimeで最後のレコードを取得して、同じセンサーからの新しい読み取り値と比較できます。 –