Как улучшить мой запрос? - PullRequest
       11

Как улучшить мой запрос?

0 голосов
/ 20 января 2012

Мне нужно вычислить число из более чем 150 000 строк (растет), но мой запрос довольно медленный.

Вот CREATE TABLE:

CREATE TABLE `device` (
  `id` int(11) NOT NULL auto_increment,
  `registration_id` varchar(255) NOT NULL,
  `creation_date` datetime NOT NULL,
  `latest_activity_date` datetime NOT NULL,
  `status` varchar(255) NOT NULL,
  `type` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `IDX_8484BF65454ADE21` (`latest_activity_date`,`status`,`type`)
) ENGINE=InnoDB AUTO_INCREMENT=160969 DEFAULT CHARSET=utf8;


CREATE TABLE `article` (
  `id` int(11) NOT NULL auto_increment,
  `summary` longtext NOT NULL,
  `creation_date` datetime NOT NULL,
  `published_date` datetime default NULL,
  `updated_date` datetime default NULL,
  PRIMARY KEY  (`id`),
  KEY `IDX_A5051EECA76ED395` (`user_id`),
  KEY `IDX_A5051EEC7B00651C9E0806AB` (`published_date`)
) ENGINE=InnoDB AUTO_INCREMENT=20216 DEFAULT CHARSET=utf8;

Мне нужнополучить количество опубликованных статей для каждого устройства с учетом их последней даты активности.

Итак, я делаю:

SELECT m.registration_id, COUNT(a.id)
FROM device m, article a 
WHERE (
    m.latest_activity_date < CURRENT_TIMESTAMP AND
    a.published_date >= m.latest_activity_date AND
    m.status = 'enabled' AND 
    a.published_date <= CURRENT_TIMESTAMP AND (
        m.registration_id <> '' OR 
        m.registration_id IS NOT NULL
    )
) AND m.type = 'foo' 
GROUP BY m.registration_id 
HAVING COUNT(a.id) > 0

Но этот запрос немного медленный (более 50 секунд для примерно 3000 статей& ~ 150000 устройств)

Я пытался EXPLAIN, но это не дает никаких подсказок.Я также попробовал явное объединение (с использованием INNER JOIN и LEFT JOIN ON a.published_date >= m.latest_activity_date, но с тем же результатом. Это также показывает, что ВСЕ строки читаются и индексы не используются (однако в качестве «возможного индекса» IDX_8484BF65454ADE21).

Есть идеи?

1 Ответ

0 голосов
/ 20 января 2012

В дополнение к отсутствию условия соединения между таблицами, оно в основном будет выполнять декартово соединение с ними (что за путаница).

Кроме того, я бы лучше скорректировал ваши индексы на основе ваших критериев "fixedсначала значения, а затем диапазон дат, чтобы уточнить ... ваш индекс

WHERE
       m.Status = "enabled" 
   AND m.Type = "foo"
   AND ... other date specific...

(статус, тип, даты ...)

наконец, почему такдлинное поле для статуса и типа ... эти типы полей были бы более сокращенными при нормальных условиях, и на МОСТЕ я бы имел такие столбцы, как 15-20 символов.Индексные страницы, содержащие до 255 символов на поле, также значительно уменьшат время запроса.

...