MySQL скорость запроса 1 миллион строк - PullRequest
4 голосов
/ 16 июля 2009

У меня проблемы с получением приличного времени запроса из большой таблицы MySQL, в настоящее время это занимает более 20 секунд. Проблема заключается в GROUP BY, так как MySQL должен запустить файловую сортировку, но я не понимаю, как мне обойти это

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

КОНСТРУКЦИЯ СТОЛОВ

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 ;

Если кто-нибудь знает, как я могу улучшить скорость, я был бы очень рад

Tom

EDIT

Я добавил новый индекс только с play_date и типом, но MySQL отказывается использовать его

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

Этот индекс был создан с использованием ALTER TABLE log ADD INDEX (type, play_date);

Ответы [ 6 ]

11 голосов
/ 16 июля 2009

Вам необходимо создать индекс по полям type И play_date.

Как это:

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

Или, альтернативно, вы можете переставить свой последний ключ следующим образом:

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

чтобы MySQL мог использовать свою левую часть в качестве ключа.

2 голосов
/ 16 июля 2009

Вы должны добавить индекс для полей, на которых вы основываете свой поиск.

В вашем случае это play_date и наберите

1 голос
/ 16 июля 2009

Вы не пользуетесь ключом с именем type_2. Это составной ключ для type, timestamp и play_date, но вы фильтруете по type и play_date, игнорируя timestamp. Из-за этого двигатель не может использовать этот ключ.

Вам следует создать индекс по полям type и play_date или удалить timestamp из ключа type_2.

Или вы можете попытаться включить timestamp в ваш текущий запрос в качестве фильтра. Но, судя по вашему текущему запросу, я не думаю, что это логично.

0 голосов
/ 04 сентября 2011

Параметр DESC заставляет MySQL не использовать индекс для ORDER BY. Вы можете оставить его ASC и выполнить итерацию набора результатов в обратном порядке на стороне клиента (?).

0 голосов
/ 16 июля 2009

Самые быстрые варианты будут

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

Это превратит этот индекс в «покрывающий индекс», что будет означать, что запрос будет обращаться только к индексу, хранящемуся в памяти, и даже не попадать на жесткий диск.

0 голосов
/ 16 июля 2009

Нужно ли указывать индекс play_date или переместить позицию в составном индексе на второе место?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...