我有一张大桌子(大约10米行,目前所有的假测试数据。)。
id用户和操作都不是唯一的,但用户只能执行一次操作。 (意思是只有一个id_user和id_action的组合。
x和y都只是1到100的INT
我已将每列编入索引。
CREATE TABLE IF NOT EXISTS `test` (
`id_user` int(11) NOT NULL,
`id_action` int(11) NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
KEY `x` (`x`),
KEY `y` (`y`),
KEY `id_user` (`id_user`),
KEY `id_action` (`id_action`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
这是我想要建立的游戏。
我想要做的是在表中搜索具有类似x分数的任何其他用户,在y指示的范围内。
例如,如果用户1执行操作1,得分为75(x),范围为10 y。我想显示所有其他得分为65-85的用户(因为范围是y设置为10)。
这就是我所拥有的,我只是在我的本地笔记本电脑上运行它......它在300秒后超时...... :(
SELECT * FROM test
WHERE
id_user != 1 AND
x BETWEEN
((SELECT x from test WHERE id_action = 1 AND id_user = 1) - (100 - (SELECT y FROM test WHERE id_action = 1 And id_user = 1)))
AND
((SELECT x from test WHERE id_action = 1 AND id_user = 1) + (100 - (SELECT y FROM test WHERE id_action = 1 And id_user = 1)));
对我拥有的10,000,000行(100个测试用户100个动作......所有随机数)的搜索失败。
我现在要调查加入表格,但我认为子选择会更有效率。我正在学习,因为我去了这里......任何建议都会受到赞赏...... :)
答案 0 :(得分:1)
将它分成2个查询要容易得多,一个用于获取x的范围,另一个用于进行实际检索。
如果您真的只想在一个查询中执行此操作,则可以尝试此操作
Select t0.* from test t0, test t1 where t1.id_user=1 AND t0.id_user !=1
AND abs(t1.x-t0.x) <= t1.y
此查询是一个自我加入,我很确定它的执行效果比查询要好得多。我还使用abs函数来过滤x范围。顺便说一下,我假设y是范围(例如10),目标x范围是从t1.x-t0.y到t1.x + t0.y.我对你的查询中的“100 - (选择y ....”)感到困惑。