我的查询需要50秒
SELECT `security_tasks`.`itemid` AS `itemid`
FROM `security_tasks`
INNER JOIN `relations` ON (`relations`.`user_id` = `security_tasks`.`user_id` AND `relations`.`relation_type_id` = `security_tasks`.`relation_type_id` AND `relations`.`relation_with` = 3001 )
security_tasks = 841321 ||中的记录关系记录= 234254
CREATE TABLE `security_tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`itemid` int(11) DEFAULT NULL,
`relation_type_id` int(11) DEFAULT NULL,
`Task_id` int(2) DEFAULT '0',
`job_id` int(2) DEFAULT '0',
`task_type_id` int(2) DEFAULT '0',
`name` int(2) DEFAULT '0'
PRIMARY KEY (`id`),
KEY `itemid` (`itemid`),
KEY `relation_type_id` (`relation_type_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1822995 DEFAULT CHARSET=utf8;
CREATE TABLE `relations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`relation_with` int(11) DEFAULT NULL,
`relation_type_id` int(11) DEFAULT NULL,
`manager_level` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `relation_with` (`relation_with`),
KEY `relation_type_id` (`relation_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1082882 DEFAULT CHARSET=utf8;
我该怎么做才能让它快速,比如快1或2秒
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE relations ref user_id,relation_with,relation_type_id relation_with 5 const 169 Using where 1 SIMPLE security_tasks ref relation_type_id,user_id user_id 5 transparent.relations.user_id 569 Using where
更新:
添加复合键可将时间缩短至20秒
ALTER TABLE security_tasks ADD INDEX(user_id,relation_type_id); ALTER TABLE关系ADD INDEX(user_id,relation_type_id); ALTER TABLE关系ADD INDEX(relation_with);
问题是当关系表包含所选用户的大数据时(关系.
relation_with` = 3001)
任何想法?
答案 0 :(得分:0)
稍微调整复合指数,不要只做两个,而是全部三个部分
ALTER TABLE关系ADD INDEX(user_id,relation_type_id,relation_with)
索引不仅必须在连接列上,而且应该基于连接列PLUS任何其他有意义的查询标准(在合理范围内,需要时间来学习更高的效率)。因此,在建议的情况下,您知道用户和类型的连接,但也特定于与...的关系,因此将其添加到同一索引中。
此外,您的安全任务表,您可以将itemID添加到索引以使其成为覆盖索引(即:覆盖连接条件和您要检索的数据元素)。这也是一种技术,不应该包含查询中的所有其他元素,但由于这是单个列可能对您的方案有意义。因此,查看“覆盖索引”,但实质上,覆盖索引限定了连接,但由于它也具有此“itemid”,因此引擎不必返回整个安全任务表的原始数据页面得到那一列。它是索引的一部分,所以它抓住任何合格的加入并且为了骑行而来,你就完成了。
ALTER TABLE security_tasks ADD INDEX(user_id,relation_type_id,itemid);
为了便于阅读,特别是对于长表名,最好使用别名
SELECT
st.itemid
FROM
security_tasks st
INNER JOIN relations r
ON st.user_id = r.user_id
AND st.relation_type_id = r.relation_type_id
AND r.relation_with = 3001