次のテーブルがあります。
CREATE TABLE `data` (
`date_time` decimal(26,6) NOT NULL,
`channel_id` mediumint(8) unsigned NOT NULL,
`value` varchar(40) DEFAULT NULL,
`status` tinyint(3) unsigned DEFAULT NULL,
`connected` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`channel_id`,`date_time`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `channels` (
`channel_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`channel_name` varchar(40) NOT NULL,
PRIMARY KEY (`channel_id`),
UNIQUE KEY `channel_name` (`channel_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
次のクエリを最適化または書き直す方法について、誰かがアドバイスをくれるかどうか疑問に思っていました。
SELECT channel_name, t0.date_time, t0.value, t0.status, t0.connected, t1.date_time, t1.value, t1.status, t1.connected FROM channels,
(SELECT MAX(date_time) AS date_time, channel_id, value, status, connected FROM data
WHERE date_time <= 1300818330
GROUP BY channel_id) AS t0
RIGHT JOIN
(SELECT MAX(date_time) AS date_time, channel_id, value, status, connected FROM data
WHERE date_time <= 1300818334
GROUP BY channel_id) AS t1
ON t0.channel_id = t1.channel_id
WHERE channels.channel_id = t1.channel_id
基本的に、各 channel_name の値、ステータス、および接続されたフィールドを 2 つの異なる時間に取得しています。t0 は常に <= t1 であるため、フィールドは t1 には存在する可能性がありますが、t0 には存在しない可能性があり、それを表示したいと考えています。そのため、RIGHT JOIN を使用しています。t1 に存在しない場合、t0 にも存在しないため、行は返されません。
問題は、サブクエリに参加しているため、インデックスを使用できないことです。最初にデータテーブルのchannel_idで自己結合を行うように書き直そうとしましたが、それは数百万行です。
t0.value = t1.value & t0.status = t1.status & t0.connected = t1.connected.
どうぞよろしくお願いいたします。