sql查询很慢

时间:2011-11-18 19:22:48

标签: php mysql sql phpmyadmin

我有一个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可以处理的限制是什么?

5 个答案:

答案 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