1

我看过很多帖子,但没有得到我的答案我有一个结构表

 subject_level_id  | tutor_id  | level_id_fk  | subject_id_fk |
  118              | 99        | 4            | 1             |
  119              | 99        | 3            | 2             |
  120              | 99        | 3            | 3             |
  121              |100        | 3            | 1             | 
  122              |100        | 4            | 2             |

我想提取教授特定级别的 1、2 或更多科目的导师的导师 ID(科目数量取决于用户选择的科目,但级别对于特定查询将是唯一的)

我在其他帖子的帮助下制定了一个查询,但如果科目数量超过两个,它会非常慢并且会变得更糟,因为我有 10,000 条导师记录,我的查询是:

select distinct
   a.tutor_id
from
   tutor_preferred_level_subject as a
inner join
   tutor_preferred_level_subject as b
   on a.level_id_fk = b.level_id_fk
where
   a.subject_id_fk = 1 and
   b.subject_id_fk = 10 and
   a.level_id_fk = 3

建议:在同一列上使用多个 WHERE 条件进行选择

这个问题和我的不同之处在于,我想要同时教授这两个科目的导师。

更新:是的,主要关注的是性能,这个查询对两个主题都很好,但是对于两个以上的主题,mysql服务器会永远处理。索引是subject_level_id并且其中有近 13000 条记录,下面的查询返回大约 6500 条结果。

正如 Jakub Sacha 所要求的,这些是

EXPLAIN select distinct
   a.tutor_id
from
   tutor_preferred_level_subject as a
inner join
   tutor_preferred_level_subject as b
   on a.level_id_fk = b.level_id_fk
where
   a.subject_id_fk = 1 and
   b.subject_id_fk = 10 and
   a.level_id_fk = 3



id  select_type     table   type    possible_keys   key     key_len     ref|
1   SIMPLE          a   ALL     NULL            NULL    NULL            NULL 
1   SIMPLE          b   ALL     NULL            NULL    NULL           NULL 

rows    Extra 
12733   Using where; Using temporary
12733   Using where; Distinct
4

3 回答 3

2

您的查询似乎没有按照您的描述进行。连接应该是 ontutor_id而不是 on level_id_fk

DISTINCT仅当(level_id_fk, subject_id_fk, tutor_id)组合不唯一时才需要:

SELECT                              
    -- DISTINCT
   a.tutor_id
FROM
   tutor_preferred_level_subject AS a
INNER JOIN
   tutor_preferred_level_subject AS b
       ON a.tutor_id = b.tutor_id
WHERE
   a.subject_id_fk = 1 AND
   a.level_id_fk = 3 AND
   b.subject_id_fk = 10 AND
   b.level_id_fk = 3 ;

此外,您应该添加一个(唯一的)索引(level_id_fk, subject_id_fk, tutor_id)以提高效率:

ALTER TABLE tutor_preferred_level_subject
  ADD INDEX level_subject_tutor_IDX
    (level_id_fk, subject_id_fk, tutor_id) ;
于 2013-01-03T07:50:57.137 回答
1

这将选择所有有两个完全匹配 (1, 10) 的不同主题的导师 ID:

SELECT
  Distinct tutor_id
FROM
  tutor_preferred_level_subject 
WHERE
  level_id_fk = 3
GROUP BY tutor_id, level_id_fk
HAVING
  Count(Distinct subject_id_fk) = 2 AND
  Sum(subject_id_fk NOT IN (1, 10)) = 0
于 2013-01-03T08:08:23.040 回答
0

似乎您不需要将表内部连接到自身,这就是当您获得越来越多的行时会导致缓慢的原因。

您说您需要“教授特定级别的 1、2 或更多科目的导师”,这基本上只是意味着您需要教授该特定级别的导师。所以尝试分组并使用 HAVING 子句(这当然需要你的数据是干净的)

SELECT a.tutor_id
FROM tutor_preferred_level_subject AS a
WHERE a.subject_id_fk IN (1,10)
  AND a.level_id_fk = 3
GROUP BY a.tutor_id
HAVING COUNT(1) > 1
于 2013-01-03T07:30:25.677 回答