[英]Any way to do this query faster with big data
This query takes around 2.23seconds and feels a bit slow ... is there anyway to make it faster.这个查询大约需要 2.23 秒,感觉有点慢......无论如何可以让它更快。 our member.id, member_id, membership_id, valid_to, valid_from has index as well.
我们的 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
EXPLAIN FOR WHAT QUERY DOING: every member has many a member_memberships and and member_memberships connect with another table called membership there we have the membership details.查询做什么的解释:每个成员都有许多成员成员成员,并且成员成员成员与另一个名为成员资格的表连接,我们有成员资格详细信息。 so query will get all members that has valid memberships and where the organization id 2513 exist on member_membership.
因此查询将获取所有具有有效成员资格的成员以及组织 ID 2513 存在于 member_membership 的位置。 Tables as following:
表如下:
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`);
Here with EXPLAIN statement => https://i.ibb.co/xjrcYWR/EXPLAIN.png这里有 EXPLAIN 语句 => https://i.ibb.co/xjrcYWR/EXPLAIN.png
Relations关系
Well I found a way to make it less to 800ms ... like this.好吧,我找到了一种方法可以将其缩短到 800 毫秒……就像这样。 Is this good way or maybe there is more we can do?
这是好方法还是我们可以做的更多?
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
NEW UPDATE.. and I think this solve the issue.. 15ms :) I added FORCE INDEX.. The FORCE INDEX hint acts like USE INDEX (index_list), with the addition that a table scan is assumed to be very expensive.新更新.. 我认为这解决了问题.. 15 毫秒 :) 我添加了 FORCE INDEX.. FORCE INDEX 提示的作用类似于 USE INDEX (index_list),此外还认为表扫描非常昂贵。 In other words, a table scan is used only if there is no way to use one of the named indexes to find rows in the table.
换句话说,仅当无法使用命名索引之一来查找表中的行时才使用表扫描。
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
How big is organization_chain
? organization_chain
有多大? If you don't need TEXT
, use a reasonably sized VARCHAR
so that it could be in an index.如果您不需要
TEXT
,请使用合理大小的VARCHAR
以便它可以在索引中。 Better yet, is there some way to get 2513 in a column by itself?更好的是,是否有某种方法可以单独在列中获得 2513?
Don't use id int(11) NOT NULL AUTO_INCREMENT,
in a many-to-many table;不要在多对多表中使用
id int(11) NOT NULL AUTO_INCREMENT,
; rather have the two columns in PRIMARY KEY
.而是在
PRIMARY KEY
有两列。
Put the ORDER BY
and LIMIT
in the subquery.将
ORDER BY
和LIMIT
放在子查询中。
Don't use IN ( SELECT ...)
, use a JOIN
.不要使用
IN ( SELECT ...)
,使用JOIN
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.