簡體   English   中英

任何使用大數據更快地執行此查詢的方法

[英]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

關系

  • 會員有很多member_membership
  • 會員有 manymember_membership
  • 所以 member_membership 就像表 member 和 members 的 join 。

好吧,我找到了一種方法可以將其縮短到 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 BYLIMIT放在子查詢中。

不要使用IN ( SELECT ...) ,使用JOIN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM