У меня есть следующая таблица с примерно 40 тысячами строк:
CREATE TABLE IF NOT EXISTS `log_ui_activity` (
`uiActivityLogEntryId` INTEGER UNSIGNED auto_increment ,
`uid` INTEGER UNSIGNED,
`from` DATETIME,
`duration` INTEGER UNSIGNED,
`nCharactersTyped` INTEGER UNSIGNED,
`nClicks` INTEGER UNSIGNED,
`hadOtherInteractions` INTEGER UNSIGNED,
`currentPage` TEXT,
`currentPageArgs` TEXT,
`currentPageStateInfo` TEXT,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
PRIMARY KEY (`uiActivityLogEntryId`)
) ENGINE=InnoDB;
с двумя дополнительными индексами, каждый на createdAt
и uid
.
Когда я запускаю следующий запрос:
SELECT *
FROM log_ui_activity
WHERE `createdAt` IN (
SELECT MAX(`createdAt`) FROM log_ui_activity
GROUP BY uid);
Он завершается в течение 0,2 с в Windows 7 и запускает XAMPP с:
MySql Ver 14.14 Distrib 5.6.20 для Win32 (x86)
Однако выполнение одного и того же запроса к точной копии данных на Mac Pro занимает несколько минут (проверено: структура, индексы и движок одинаковы) с MAMP с:
MySql Ver 14.14 Distrib 5.5.38 для osx10.6 (i386) с использованием оболочки EditLine
Я даже пробовал разных клиентов ...
Есть идеи, как запрос может быть намного медленнее, даже если все / кажется идентичным?
ОБНОВЛЕНИЕ
Как предлагается в ответе, использование JOIN
вместо IS IN
исправляет ситуацию. Для справки это выражение JOIN
:
SELECT *
FROM log_ui_activity a
INNER JOIN (
(SELECT MAX(`createdAt`) createdAt FROM log_ui_activity GROUP BY uid) tmp
)
ON (a.createdAt = tmp.createdAt);
EXPLAIN
показывает то же самое. Однако я думал, что создание индекса для существующей таблицы (с использованиемCREATE INDEX
) фактически построит индекс. Я также обнаружил, что InnoDB не поддерживает REPAIR, так что теперь я пытаюсь использовать методmysqldump
. - person Domi   schedule 31.03.2015