[英]SQL query optimization - multiple rows from another table
I have my tables like this (currently)我有这样的桌子(目前)
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `user_opts` (
`user_id` bigint(20) NOT NULL,
`opt1` varchar(64) DEFAULT NULL,
`opt2` TINYINT(4) DEFAULT NULL,
`opt3` varchar(64) DEFAULT NULL,
KEY `user_id_idx` (`user_id`)
);
I want to be able to do queries like this:我希望能够进行这样的查询:
SELECT DISTINCT name
FROM users
WHERE
id = 1 AND (
EXISTS ( SELECT 1 FROM user_opts WHERE user_opts.user_id = users.id AND user_opts.opt1 = 'a' AND user_opts.opt3 = 'c') OR
EXISTS ( SELECT 1 FROM user_opts WHERE user_opts.user_id = users.id AND user_opts.opt1 = 'b' AND user_opts.opt2 = 1)
);
and this:和这个:
SELECT DISTINCT name
FROM users
WHERE
id = 1 AND (
EXISTS ( SELECT 1 FROM user_opts WHERE user_opts.user_id = users.id AND user_opts.opt1 = 'a' AND user_opts.opt3 = 'e') AND
EXISTS ( SELECT 1 FROM user_opts WHERE user_opts.user_id = users.id AND user_opts.opt1 = 'b' AND user_opts.opt2 = 1)
);
The obvious problem I'm starting to have is that the more users the queries goes slower and slower.我开始遇到的一个明显问题是,用户越多,查询的速度就越慢。 I know I could refactor the first type of the queries (using
OR
) by JOINing the table, but the JOIN itself would be slow since I can't have a PK on the user_opts
table.我知道我可以通过 JOIN 表重构第一种类型的查询(使用
OR
),但是 JOIN 本身会很慢,因为我不能在user_opts
表上进行 PK。
How could I restructure my data (and the queries) so I can do efficient/fast searches?我怎样才能重组我的数据(和查询),以便我可以进行高效/快速的搜索? Preferably, if possible, I would like to keep the same queries for both
AND
and OR
types, just switching the condition between the two.最好,如果可能的话,我想对
AND
和OR
类型保持相同的查询,只是在两者之间切换条件。
Thanks!谢谢!
You can use aggregation:您可以使用聚合:
select user_id
from user_opts uo
where opt3 = 'c' or opt2 = 1
group by user_id
having sum(opt3 = 'c') >= 1 and
sum(opt2 = 1) >= 1;
This handles the case when the two options are set on the same row in user_opts
.当两个选项设置在
user_opts
的同一行时,这将处理这种情况。
Adding these two indexes would speed up the EXISTS
:添加这两个索引将加快
EXISTS
:
INDEX(user_id, opt1, opt3)
INDEX(user_id, opt1, opt2)
Your schema is a variant on EAV, which is notoriously inefficient and clumsy.您的架构是 EAV 的变体,众所周知,它效率低下且笨拙。 Is there a good reason not to have opt2 and opt3 in
users
? users
中有没有 opt2 和 opt3 的充分理由?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.