排序和组的MySQL查询优化

时间:2013-06-04 12:20:10

标签: mysql sorting optimization

我有这样的查询...

SELECT SQL_CACHE area3, area, area2, COUNT( area ) AS total
FROM wpthillsdatabase
GROUP BY area
ORDER BY area3 ASC , area ASC

它的EXPLAIN说它正在使用filesort,没有索引和临时表......

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  wpthillsdatabaseV12 ALL NULL    NULL    NULL    NULL    9334    Using temporary; Using filesort

是否可以进一步优化以删除带有索引的文件存储或临时表,或者它是否与它一样好?

FYI TABLE的结构如下......

CREATE TABLE `wpthillsdatabase` (
  `hillnumber` varchar(6) NOT NULL default '',
  `wikipedia` varchar(100) NOT NULL default '',
  `hillname` varchar(100) NOT NULL default '',
  `meters` char(6) NOT NULL default '',
  `GridZN` char(2) NOT NULL default '',
  `GridEast` char(5) NOT NULL default '',
  `GridNorth` char(5) NOT NULL default '',
  `numeast` char(7) NOT NULL default '',
  `numnorth` char(7) NOT NULL default '',
  `areadecimal` decimal(5,2) NOT NULL default '0.00',
  `area` varchar(3) NOT NULL default '',
  `area2` varchar(100) NOT NULL default '',
  `maps` varchar(100) NOT NULL default '',
  `waypointname` char(6) character set latin1 collate latin1_bin NOT NULL default '',
  `latitude` decimal(10,8) NOT NULL default '0.00000000',
  `longitude` decimal(10,7) NOT NULL default '0.0000000',
  `area3` smallint(2) NOT NULL default '0',
  `dip` decimal(5,1) NOT NULL default '0.0' COMMENT 'col height (m)',
  `climbedbytotal` smallint(6) NOT NULL default '0',
  `trigID` varchar(6) NOT NULL default '',
  `trigEast` varchar(7) NOT NULL default '',
  `trigNorth` varchar(7) NOT NULL default '',
  `trigLat` varchar(10) NOT NULL default '',
  `trigLon` varchar(10) NOT NULL default '',
  `SummitInfo` varchar(290) NOT NULL default '',
  PRIMARY KEY  (`hillnumber`,`area3`),
  UNIQUE KEY `meters` (`meters`,`hillnumber`),
  UNIQUE KEY `SortIndex1` (`hillnumber`,`hillname`,`meters`),
  UNIQUE KEY `NearByHills` (`numeast`,`numnorth`,`hillnumber`),
  UNIQUE KEY `hillnumber_only` (`hillnumber`),
  UNIQUE KEY `Area3_Sort` (`area3`,`hillnumber`,`hillname`,`meters`),
  UNIQUE KEY `GirdZN_sort` (`GridZN`,`hillnumber`,`hillname`,`meters`),
  UNIQUE KEY `hil_lat_lon` (`hillnumber`,`latitude`,`longitude`),
  KEY `trigID` (`trigID`,`hillname`,`meters`),
  KEY `climbedbytotal` (`climbedbytotal`),
  KEY `hillname` (`hillname`,`meters`),
  KEY `area3` (`area3`,`hillnumber`),
  KEY `hillname_only` (`hillname`),
  KEY `area3_trigID` (`area3`,`trigID`),
  KEY `Area_text` (`area`,`area3`),
  KEY `dip_area3` (`dip`,`area3`),
  KEY `lat_lon` (`latitude`,`longitude`,`meters`),
  KEY `trigID_area3` (`trigID`,`area3`),
  KEY `numeast_north` (`numeast`,`numnorth`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

Ta

菲尔

2 个答案:

答案 0 :(得分:2)

您的要求意味着什么:

  • GROUP BY area可以使用以area
  • 开头的索引进行优化
  • ORDER BY are3 ASC, area ASC可以使用以area3, area
  • 开头的索引进行优化

但是没有索引可以用于同时优化这两个位。

如果您能够更改结果,请尝试更改排序顺序:ORDER BY area ASC, area3 ASC

正如bobwienholt建议的那样,您可以在表上测试覆盖索引,以至少优化GROUP表的提取,但索引应该以{{1​​}}开头:{{1 }}

但是,如果您的表变大并且经常更新,那么如果您的表经常更新,则将索引相乘(特别是当它们包含area列时)可能会影响性能。根据具体情况,最好从mysql中提取未排序的数据,并在服务器代码中对它们进行过滤/排序(php / ruby​​ / python ...)

答案 1 :(得分:1)

您可以通过将area2列添加到结尾来将“Area_text”转换为覆盖索引。不确定它是否有助于优化GROUP BY或ORDER BY,但它将允许MySQL仅使用该索引来处理查询,这应该加快它的速度。