我有以下表格:
1。学生(stuID,classId,addId,name)
2。 student_address(addId,stuId,city,state)
3。 student_hobby(stuId,业余爱好)
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
考虑结果都得到结果集。
因此,让我建议哪种方法可以更好地用于繁重的数据库。
谢谢,
答案 0 :(得分: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 index:
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);