我的下表有大约40k行:
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);
在Windows 7上以0.2秒结束并使用:
运行XAMPPMySql Ver 14.14 Distrib 5.6.20,for Win32(x86)
但是,在运行MAMP的Mac Pro(已验证:结构,索引和引擎都完全相同)上的数据的精确副本上运行完全相同的查询需要几分钟时间:
MySql Ver 14.14 Distrib 5.5.38,for osx10.6(i386)using EditLine wrapper
我甚至尝试过不同的客户......
任何想法如何查询如此慢,即使一切都/看起来相同?
更新
正如答案中所建议的那样,使用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);
答案 0 :(得分:1)
IN ( SELECT ... )
曾经表现糟糕。您通常可以通过将其变为JOIN
来“修复”它。问题是每次需要SELECT
时都会重新执行IN
。
In 5.6.5,优化器做得更漂亮。您可以通过EXPLAIN EXTENDED SELECT ...
,然后SHOW WARNINGS
来查看“更改”。