我有一个phpmyadmin数据库,我需要搜索1 000 000条记录。每周都会添加50万条记录。
所以,这就是我需要的:
location_id value date time name lat lng
3 234 2011-11-18 19:50:00 Amerongen beneden 5.40453 51.97486
4 594 2011-11-18 19:50:00 Amerongen boven 5.41194 51.97507
我使用此查询执行此操作:
SELECT location_id, value, date, time, locations.name, locations.lat, locations.lng FROM
(
SELECT location_id, value, date, time from `measurements`
LEFT JOIN units ON (units.id = measurements.unit_id)
WHERE units.name='Waterhoogte'
ORDER BY measurements.date DESC, measurements.time DESC
) as last_record
LEFT JOIN locations on (locations.id = location_id)
GROUP BY location_id
需要30秒。我怎样才能改善这个?这是我的结构:
CREATE TABLE IF NOT EXISTS `locations` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`code` varchar(255) NOT NULL,
`lat` varchar(10) NOT NULL,
`lng` varchar(10) NOT NULL,
`owner_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=244 ;
-- --------------------------------------------------------
--
-- Table structure for table `measurements`
--
CREATE TABLE IF NOT EXISTS `measurements` (
`id` int(11) NOT NULL auto_increment,
`date` date NOT NULL,
`time` time NOT NULL,
`value` varchar(255) NOT NULL,
`location_id` int(11) NOT NULL,
`unit_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=676801 ;
-- --------------------------------------------------------
--
-- Table structure for table `owner`
--
CREATE TABLE IF NOT EXISTS `owner` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-- --------------------------------------------------------
--
-- Table structure for table `units`
--
CREATE TABLE IF NOT EXISTS `units` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
`unit_short` varchar(255) NOT NULL,
`owner_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=44 ;
phpmyadmin可以处理的限制是什么?
答案 0 :(得分:4)
在units.name上创建索引是一个好的开始。 您还应该重新考虑要撤回的数据量。 有人真的要筛选那么多记录。更改查询以限制记录数,并考虑涉及分页机制的UI界面。
答案 1 :(得分:2)
您需要在units.name上添加索引或唯一索引。
答案 2 :(得分:1)
添加以下索引:
unit.name和unit.id上的复合索引(覆盖索引) measurement.date和measurements.time的综合指数 location.id上的索引
答案 3 :(得分:0)
您应尝试在units.name上创建索引作为第一步。但要明白,与索引存在权衡 - 读取操作会更快,但可能会减慢写入操作的速度。如果您对此感到担心,或者您受到慢速写入的影响,那么您可能希望尝试在units.name中的较少数量的字符上创建索引。
例如,要在units.name的前12个字符上声明索引,您需要声明以下内容:
CREATE INDEX first_twelve ON units(name(12));
同样,如果您没有注意到仅仅抛出索引会产生任何不良影响,则可能没有必要这样做,但这是需要牢记的。
答案 4 :(得分:0)
SELECT measurements.location_id, measurements.value, measurements.date, measurements.time, locations.name, locations.lat, locations.lng
FROM measurements
LEFT JOIN units ON units.id = measurements.unit_id
LEFT JOIN locations ON locations.id = measurements.location_id
WHERE units.id = 4
GROUP BY measurements.location_id
ORDER BY measurements.date DESC, measurements.time DESC