MySQL - 搜索自联接和范围或数据

时间:2013-07-21 14:31:01

标签: mysql search join indexing

我的当地社区中心的任务是在情人节及时制作“新婚”型游戏,所以不要急!

所以,我们有50多对相互认识的夫妻,他们之前会被问到100个问题。每个问题都有用户响应和允许误差范围的范围(此范围配额将受到限制)。然后他们可以选择他们认为合作伙伴回答的内容,误差范围相同。

EG(我会像我和我的GF一样玩一轮):

问题:你喜欢水果吗? 我对水果非常挑剔,所以我会给出100分的低分...说20但是我喜欢什么,我喜欢并认为我的GF可能会认为我会提出更高的答案,所以我的误差我'允许将是30岁。 我认为她喜欢水果,至少会吃90 ..但是她喜欢很多食物,所以可能只是将它降低,所以我会给她20分的余量。

好的,重复这个过程100个问题和50对夫妇。

我留下了这样一张桌子:

u_a =用户回答

u_l =错误级别的用户边距

p_a =合作伙伴回答

p_l =合作伙伴误差水平

CREATE TABLE IF NOT EXISTS `large` (
`id_user` int(11) NOT NULL,
`id_q` int(11) NOT NULL,
`u_a` int(11) NOT NULL,
`u_l` int(11) NOT NULL,
`p_a` int(11) NOT NULL,
`p_l` int(11) NOT NULL,
KEY `id_user` (`id_user`,`id_q`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Stackoverflow Test';

所以我的行将在上一个示例中:

(1,1,20,30,90,20)

我的任务是搜索所有用户,看看谁是最好的比赛50 ...(并希望夫妻们在一起很好!)。

我想在数据库中搜索我的合作伙伴的答案与其答案匹配的所有用户,但是对于每个用户。

这是我到目前为止所得到的(注意我已经注释掉了一些代码,这是因为我正在尝试两种方式,不确定什么是最好的):

SELECT
match.id_user,
count(*) as count
from `large` `match`
INNER JOIN `large` `me` ON me.id_q = match.id_q
WHERE
me.id_user = 1 AND
match.id_user != 1 AND
GREATEST(abs(me.p_a - match.u_a), 0) <= me.p_l
AND
GREATEST(abs(match.p_a - me.u_a), 0) <= match.p_l 

#match.u_a BETWEEN GREATEST(me.p_a - me.p_l, 0) AND (me.p_a + me.p_l)
#AND
#me.u_a BETWEEN GREATEST(match.p_a - match.p_l, 0) AND (match.p_a + match.p_l)

GROUP BY match.id_user

ORDER BY count DESC

我今天的问题是:

此查询需要年龄!我想在游戏过程中做到这一点,让用户有机会在晚上更改答案并获得即时结果,因此必须快速。当我查找所有比赛(用户1)时,我正在看40秒。

我现在正在阅读有关数据库引擎和索引的信息,以确保我尽我所能......但欢迎提出建议!

干杯和PHEW!

1 个答案:

答案 0 :(得分:0)

您的查询不应该在一个小的数据集上花费40秒。知道发生了什么的最好方法是在查询之前使用explain

但是,我怀疑问题是me的情况。 MySQL引擎可能会为所有用户创建所有可能的组合,然后过滤掉你。您可以通过修改此代码来测试:

from `large` `match` INNER JOIN
     `large` `me`
     ON me.id_q = match.id_q
WHERE me.id_user = 1 AND
      match.id_user != 1 AND . . . .

要:

from `large` `match` INNER JOIN
     (select me.*
      from `large` `me`
      where me.id_user = 1
     ) me
     ON me.id_q = match.id_q
WHERE match.id_user != 1 AND . . . .

此外,以下索引可能有助于查询:large(id_user, id_q)large(id_q)