我有两张桌子,在第一张桌子上我有一个设备列表,上面有他们的ID,帐号以及设备更新自己状态的最后一个时间戳。这张表很小,有大约50K行。
在第二张表格中,我收到了所有设备的所有报告。这张桌很重,此时此刻有大约200.000.000(200万)行。
大表有三个PK列accountID,deviceID和timestamp
我正在从VB.NET应用程序进行查询
从第一个小表中我得到一个带有最后一个时间戳的deviceID列表,以便进行查询,从而更快地在大表上获得一些行。
我面临的问题是我得到了一些我不需要的数据。
示例:
accountID deviceID timestamp
1 A 23
1 A 24
1 A 25
1 B 23
所以,如果我想获得带有最后一个时间戳的行
SELECT* FROM clients.Events
WHERE timestamp IN ('25','23')
AND deviceID IN ('A','B')
AND accountID IN ('1')
我得到了
accountID deviceID timestamp
1 A 23
1 A 25
1 B 23
我需要
accountID deviceID timestamp
1 A 25
1 B 23
那么,有没有办法将时间戳与deviceID相匹配?
我知道我可以使用MAX子句但是,正如我之前所说,事件基数很大,我需要尽可能快的结果和MAX子句检查整个表并花费太多时间。
大型活动表是InnoDB。
DDL
CREATE TABLE `Events` (
`accountID` varchar(32) NOT NULL,
`deviceID` varchar(32) NOT NULL,
`timestamp` int(10) unsigned NOT NULL,
`statusCode` int(10) unsigned NOT NULL,
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`gpsAge` int(10) unsigned DEFAULT NULL,
`speedKPH` double DEFAULT NULL,
`heading` double DEFAULT NULL,
`altitude` double DEFAULT NULL,
`transportID` varchar(32) DEFAULT NULL,
`inputMask` int(10) unsigned DEFAULT NULL,
`outputMask` int(10) unsigned DEFAULT NULL,
`address` varchar(90)CHARACTER SET utf8 DEFAULT NULL,
`dataSource` varchar(32) DEFAULT NULL,
`rawData` text,
`distanceKM` double DEFAULT NULL,
`odometerKM` double DEFAULT NULL,
`geozoneIndex` int(10) unsigned DEFAULT NULL,
`geozoneID` varchar(32) DEFAULT NULL,
`creationTime` int(10) unsigned DEFAULT NULL,
`streetAddress` varchar(90)CHARACTER SET utf8 DEFAULT NULL,
`city` varchar(40)CHARACTER SET utf8 DEFAULT NULL,
`stateProvince` varchar(40)CHARACTER SET utf8 DEFAULT NULL,
`postalCode` varchar(16)CHARACTER SET utf8 DEFAULT NULL,
`country` varchar(40)CHARACTER SET utf8 DEFAULT NULL,
`subdivision` varchar(32)CHARACTER SET utf8 DEFAULT NULL,
`speedLimitKPH` double DEFAULT NULL,
`isTollRoad` tinyint(4) DEFAULT NULL,
`gpsFixType` smallint(5) unsigned DEFAULT NULL,
`horzAccuracy` double DEFAULT NULL,
`vertAccuracy` double DEFAULT NULL,
`HDOP` double DEFAULT NULL,
`satelliteCount` smallint(5) unsigned DEFAULT NULL,
`batteryLevel` double DEFAULT NULL,
`batteryVolts` double DEFAULT NULL,
`signalStrength` double DEFAULT NULL,
PRIMARY KEY (`accountID` , `deviceID` , `timestamp` , `statusCode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
答案 0 :(得分:0)
SELECT CE.*
FROM clients.events CE
INNER JOIN (SELECT accountID, DeviceID, Max(timestamp) TS
FROM clients.events
GROUP YB accountID, DeviceID) CE2
on CE.AccountID=CE2.accountId
and CE.DeviceID= CE2.DeviceID
and CE.TimeStamp = CE2.TS
上面的内容为您提供每个设备和帐户的最大时间戳记录 现在你只需要过滤......
WHERE DeviceID in ('A','B') and accountID = '1' and timestamp in ('25','23')
使用适当的索引应该有效地工作。