[英]Any way to do this query faster with big data
这个查询大约需要 2.23 秒,感觉有点慢......无论如何可以让它更快。 我们的 member.id、member_id、membership_id、valid_to、valid_from 也有索引。
select *
from member
where (member.id in ( select member_id from member_membership mm
INNER JOIN membership m ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
查询做什么的解释:每个成员都有许多成员成员成员,并且成员成员成员与另一个名为成员资格的表连接,我们有成员资格详细信息。 因此查询将获取所有具有有效成员资格的成员以及组织 ID 2513 存在于 member_membership 的位置。 表如下:
CREATE TABLE `member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
CREATE TABLE `member_membership` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`membership_id` int(11) DEFAULT NULL,
`member_id` int(11) DEFAULT NULL,
`organization_chain` text DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `member_membership_to_membership` (`membership_id`),
KEY `member_membership_to_member` (`member_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
CREATE TABLE `membership` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`valid_to` datetime DEFAULT NULL,
`valid_from` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `valid_to` (`valid_to`),
KEY `valid_from` (`valid_from`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
ALTER TABLE `member_membership` ADD CONSTRAINT `member_membership_to_membership` FOREIGN KEY (`membership_id`) REFERENCES `membership` (`id`);
ALTER TABLE `member_membership` ADD CONSTRAINT `member_membership_to_member` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`);
这里有 EXPLAIN 语句 => https://i.ibb.co/xjrcYWR/EXPLAIN.png
关系
好吧,我找到了一种方法可以将其缩短到 800 毫秒……就像这样。 这是好方法还是我们可以做的更多?
select *
from member
where (member.id in ( select member_id from member_membership mm FORCE INDEX (PRIMARY)
INNER JOIN membership m ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
新更新.. 我认为这解决了问题.. 15 毫秒 :) 我添加了 FORCE INDEX.. FORCE INDEX 提示的作用类似于 USE INDEX (index_list),此外还认为表扫描非常昂贵。 换句话说,仅当无法使用命名索引之一来查找表中的行时才使用表扫描。
select *
from member
where (member.id in ( select member_id from member_membership mm FORCE INDEX (member_membership_to_member)
INNER JOIN membership m FORCE INDEX (organization_to_membership) ON mm.membership_id = m.id
where instr(organization_chain, 2513) and m.valid_to > NOW() and m.valid_from < NOW() ) )
order by id desc
limit 10 offset 0
organization_chain
有多大? 如果您不需要TEXT
,请使用合理大小的VARCHAR
以便它可以在索引中。 更好的是,是否有某种方法可以单独在列中获得 2513?
不要在多对多表中使用id int(11) NOT NULL AUTO_INCREMENT,
; 而是在PRIMARY KEY
有两列。
将ORDER BY
和LIMIT
放在子查询中。
不要使用IN ( SELECT ...)
,使用JOIN
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.