使用DISTINCT和GROUP BY后,mySQL查询非常慢?

时间:2012-08-27 08:25:18

标签: mysql performance group-by distinct

我有以下结构的表:

-- Table structure for table `temp_app`
--

CREATE TABLE IF NOT EXISTS `temp_app` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `vid` int(5) NOT NULL,
  `num` varchar(64) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `vid` (`vid`),
  KEY `num` (`num`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=69509;

-- Table structure for table `inv_flags`
--

CREATE TABLE IF NOT EXISTS `inv_flags` (
  `num` varchar(64) NOT NULL,
  `vid` int(11) NOT NULL,
  `f_special` tinyint(1) NOT NULL, /*0 or 1*/
  `f_inserted` tinyint(1) NOT NULL, /*0 or 1*/
  `f_notinserted` tinyint(1) NOT NULL, /*0 or 1*/
  `userID` int(11) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY `num` (`num`),
  KEY `userID` (`userID`),
  KEY `vid` (`vid`),
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

以下查询的执行时间为9秒,显示30条记录。有什么问题?

SELECT date_format(ifs.`timestamp`,'%y/%m/%d') as `date`
                ,count(DISTINCT ta.num) as inserted /*Unique nums*/
                ,SUM(ifs.f_notinserted) as not_inserted
                ,SUM(ifs.f_special)  as special
                ,count(ta.num) as links /*All nums*/
                from inventory_flags ifs
                LEFT JOIN temp_app ta ON ta.num = ifs.num AND ta.vid = ifs.vid
                WHERE ifs.userID = 3
                GROUP BY date(ifs.`timestamp`) DESC LIMIT 30

分析结果

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  ifs ref userID  userID  4   const   12153   Using where
1   SIMPLE  ta  ref vid,num num 194 ifs.num 1   

1 个答案:

答案 0 :(得分:1)

COUNT DISTINCT有时会导致MySql性能下降。试试这个:

select count(*) from (select distinct...

因为它有时会阻止MySql将整个中间结果写入磁盘。

以下是MySql错误信息:

http://bugs.mysql.com/bug.php?id=21849