1

我有以下表格:
1. student (stuID, classId, addId,name)
2. student_address (addId, stuId, city, state)
3. student_hobby (stuId, hobby)
4. student_class (classId, stuId, className)

我有两个选项:-

一个选项是:

查询以使用连接获取学生的所有详细信息:-

select s.name, sd.city, sc.className
from student as s join student_address sd on s.addId = sd.addId 
inner join student_class sc on sc.classId = s.classId 
inner join student_hobby sh on sh.stuId = s.stuId
where sh.hobby REGEXP 'cricket|footbal';


另一种选择是使用存储功能:

select s.name, sd.city, sc.className
from student as s join student_address sd on s.addId = sd.addId 
inner join student_class sc on sc.classId = s.classId 
where f_searchHobby(s.stuId,'cricket|footbal')=1;


create function f_searchHobby( 
sId int,
matches varchar(100)
 ) returns int 
begin
 select count(*) into @count from student_hobby where hobby regexp matches and stuId = sId;
 if @count > 1 then
  return 1 ;
 else 
  return 0; 
 end if; 
end



考虑两个结果都得到结果集。
所以让我建议哪种方法更适合重型数据库。


谢谢,

4

1 回答 1

0

您应该使用的存储函数示例将为外部查询的每一行SELECT COUNT(*)执行一个查询。这相当于一个相关的子查询,性能很差。

您应该使用的 REGEXP 示例也很糟糕,但不如存储的函数那么糟糕。REGEXP 不能使用索引,它总是需要表扫描,将表达式应用于表的每一行。

您显示的搜索最好使用IN( )谓词:

select s.name, sd.city, sc.className
from student as s join student_address sd on s.addId = sd.addId 
inner join student_class sc on sc.classId = s.classId 
inner join student_hobby sh on sh.stuId = s.stuId
where sh.hobby IN ('cricket', 'footbal');

这假设每个爱好都单独存储在单独的行中。

如果您将爱好列表存储在一行的字符串中,那么您应该使用FULLTEXT 索引

select s.name, sd.city, sc.className
from student as s join student_address sd on s.addId = sd.addId 
inner join student_class sc on sc.classId = s.classId 
inner join student_hobby sh on sh.stuId = s.stuId
where MATCH(sh.hobby) AGAINST ('cricket footbal' IN BOOLEAN MODE);
于 2013-08-31T07:31:14.963 回答