【发布时间】:2020-05-10 18:51:10
【问题描述】:
我的桌子是这样的(目前)
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`)
);
我希望能够进行这样的查询:
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)
);
还有这个:
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)
);
我开始遇到的一个明显问题是,用户越多,查询就越慢。我知道我可以通过 JOIN 表重构第一种类型的查询(使用 OR),但是 JOIN 本身会很慢,因为我无法在 user_opts 表上进行 PK。
如何重组我的数据(和查询),以便进行高效/快速的搜索?最好,如果可能的话,我希望对 AND 和 OR 类型保持相同的查询,只是在两者之间切换条件。
谢谢!
【问题讨论】:
-
这是 1:n 关系还是 1:1?
-
1:n,这就是为什么我不能在
user_opts表上进行 PK(至少使用当前结构)
标签: mysql sql mariadb entity-attribute-value sql-optimization