Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL 1 millon row query speed

I'm having trouble getting a decent query time out of a large MySQL table, currently its taking over 20 seconds. The problem lies in the GROUP BY as MySQL needs to run a filesort but I don't see how I can get around this

QUERY:

SELECT play_date, COUNT(DISTINCT(email)) AS count 
FROM log 
WHERE type = 'play'
AND play_date BETWEEN '2009-02-23' 
AND '2009-02-24'
GROUP BY play_date 
ORDER BY play_date desc

EXPLAIN:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE          log     ALL     type,type_2     NULL    NULL    NULL    530892  Using where; Using filesort

TABLE STRUCTURE

CREATE TABLE IF NOT EXISTS `log` (
  `id` int(11) NOT NULL auto_increment,
  `email` varchar(255) NOT NULL,
  `type` enum('played','reg','friend') NOT NULL,
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `play_date` date NOT NULL,
  `email_refer` varchar(255) NOT NULL,
  `remote_addr` varchar(15) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `email` (`email`),
  KEY `type` (`type`),
  KEY `email_refer` (`email_refer`),
  KEY `type_2` (`type`,`timestamp`,`play_date`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=707859 ;

If anyone knows how I could improve the speed I would be very greatful

Tom

EDIT

I've added the new index with just play_date and type but MySQL refuses to use it

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE          log     ALL     play_date   NULL    NULL    NULL    801647  Using where; Using filesort

This index was created using ALTER TABLE log ADD INDEX (type, play_date);

like image 307
Tom Avatar asked Dec 10 '22 20:12

Tom


2 Answers

You need to create index on fields type AND play_date.

Like this:

ALTER TABLE `log` ADD INDEX (`type`, `play_date`);

Or, alternately, you can rearrange your last key like this:

KEY `type_2` (`type`,`play_date`,`timestamp`)

so MySQL can use its left part as a key.

like image 51
Kuroki Kaze Avatar answered Dec 28 '22 15:12

Kuroki Kaze


You should add an index on the fields that you base your search on.

In your case it play_date and type

like image 32
Thirler Avatar answered Dec 28 '22 14:12

Thirler