有人帮我想出这个查询,但它仍然太慢;顺序让它变慢了,我认为它没有使用我的索引我希望有人能帮我解决这个问题:D是的,我读了手册页,但是我看不懂。
查询:
EXPLAIN SELECT u.id, u.url, u.title, u.numsaves
FROM urls u
JOIN tags t ON t.url_id = u.id
AND t.tag = 'osx'
ORDER BY u.numsaves DESC
LIMIT 20
Showing rows 20 - 19 ( 20 total, Query took 1.5395 sec) [numsaves: 6130 - 2107]
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ref tag_id tag_id 767 const 49432 Using where; Using index; Using temporary; Using filesort
1 SIMPLE u eq_ref PRIMARY,id_numsaves_IX PRIMARY 4 jcooper_whatrethebest_urls.t.url_id 1
数据库:
CREATE TABLE `urls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` text NOT NULL,
`domain` text,
`title` text NOT NULL,
`description` text,
`numsaves` int(11) NOT NULL,
`firstsaved` varchar(256) DEFAULT NULL,
`md5` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `md5` (`md5`),
KEY `id_numsaves_IX` (`id`,`numsaves`)
) ENGINE=InnoDB AUTO_INCREMENT=2958560 DEFAULT CHARSET=utf8
CREATE TABLE `tags` (
`url_id` int(11) DEFAULT NULL,
`hash` varchar(255) NOT NULL,
`tag` varchar(255) NOT NULL,
UNIQUE KEY `tag_id` (`tag`,`url_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
我认为你的查询的主要问题是你选择的索引。
1) tags
在tag
和url_id
上有化合物UNIQUE KEY
,但没有化合物PRIMARY KEY
。
如果不出意外的话,您应该将其设置为主要的—这可能会对性能有所帮助。此外,您可能需要仔细查看VARCHAR(255)
是否真的是您的标记所必需的。这使得指数相当大。
2)在numsaves
上添加一个单独的索引,因为你是按它排序的。id
和numsaves
的复合索引在这里没有帮助。
3) EXPLAIN
说您在tags
中有49432行与"osx"
匹配。这是相当多余的。您可能希望将标记表分成两个,一个包含文本,而另一个包含指向urls
的N:M链接。