MySQL慢慢加入.任何加速的方法

kay*_*yem 6 php mysql join date

我有2张桌子.1是音乐,2是listenTrack.listenTrack跟踪每首歌曲的独特播放.我试图获得本月流行歌曲的结果.我得到了我的结果,但他们只是花了太长时间.下面是我的表和查询

430,000行

CREATE TABLE `listentrack` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `sessionId` varchar(50) NOT NULL,
    `url` varchar(50) NOT NULL,
    `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `ip` varchar(150) NOT NULL,
    `user_id` int(11) DEFAULT NULL,
     PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=731306 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

12500行

CREATE TABLE `music` (
   `music_id` int(11) NOT NULL AUTO_INCREMENT,
   `user_id` int(11) NOT NULL,
   `title` varchar(50) DEFAULT NULL,
   `artist` varchar(50) DEFAULT NULL,
   `description` varchar(255) DEFAULT NULL,
   `genre` int(4) DEFAULT NULL,
   `file` varchar(255) NOT NULL,
   `url` varchar(50) NOT NULL,
   `allow_download` int(2) NOT NULL DEFAULT '1',
   `plays` bigint(20) NOT NULL,
   `downloads` bigint(20) NOT NULL,
   `faved` bigint(20) NOT NULL,
   `dateadded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`music_id`)
) ENGINE=MyISAM AUTO_INCREMENT=15146 DEFAULT CHARSET=utf8


SELECT COUNT(listenTrack.url) AS total, listenTrack.url 
FROM listenTrack
LEFT JOIN music ON music.url = listenTrack.url
WHERE DATEDIFF(DATE(date_created),'2009-08-15') = 0
GROUP BY listenTrack.url
ORDER BY total DESC
LIMIT 0,10
Run Code Online (Sandbox Code Playgroud)

这个查询不是很复杂,行不是太大,我不这么认为.

有什么方法可以加快速度吗?或者你能提出更好的解决方案吗?这将是每个月开始的一个cron工作,但我也想做一天的结果.

哦,顺便说一句,我在本地运行,运行时间超过4分钟,但是在生产中它需要大约45秒

Jef*_*ver 12

我更像是一个SQL Server人,但这些概念应该适用.

我要添加索引:

  1. 在ListenTrack上,使用url和date_created添加索引
  2. 在音乐上,使用网址添加索引

这些索引应该极大地加快查询速度(我最初将表名混淆了 - 在最新的编辑中修复).


Cod*_*lan 6

在大多数情况下,您还应该索引JOIN中使用的任何列.在您的情况下,您应该索引listentrack.urlmusic.url

@jeff s - 索引music.date_created没有帮助,因为你首先通过一个函数运行它,所以MySQL不能在该列上使用索引.通常,您可以重写查询,以便静态使用索引引用列,如:

DATEDIFF(DATE(date_created),'2009-08-15') = 0
Run Code Online (Sandbox Code Playgroud)

date_created >= '2009-08-15' and date_created < '2009-08-15'
Run Code Online (Sandbox Code Playgroud)

这将过滤掉2009-08-15中的记录,并允许该列上的任何索引成为候选.请注意,MySQL可能不会使用该索引,它取决于其他因素.

你最好的选择是打开双重索引listentrack(url, date_created) ,然后打开另一个索引music.url

这两个索引将涵盖此特定查询.

请注意,如果您运行EXPLAIN此查询,您仍然会得到一个,using filesort因为它必须将记录写入磁盘上的临时表以执行ORDER BY.

通常,您应始终运行查询,EXPLAIN以了解MySQL将如何执行查询,然后从那里开始.查看EXPLAIN文档:

http://dev.mysql.com/doc/refman/5.0/en/using-explain.html