2013-08-31 19 views
1

我有以下表格:
1.學生(stuID,CLASSID,ADDID,名)
2. student_address(ADDID,stuId,城市,州)
3. student_hobby(stuId,愛好)
4. student_class( CLASSID,stuId,類名)

我有兩個選擇: -

一種選擇是:

查詢中使用,以獲得學生的所有詳細參加辦法: -
哪一個更好的在JOIN中使用sql查詢或查詢中的存儲函數?

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

存儲的功能,例如,你應該是要執行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); 
+0

感謝比爾Karwin, –

+0

感謝比爾Karwin, 我同意給你兩個建議,但假設我有兩種愛好,比如聽音樂,聽歌。我的要求是隻傳遞關鍵字'聆聽'在哪裏條款,如果我不使用mYISAM。那麼我應該怎麼做才能讓聽音樂和聽歌都結果呢? –

+0

我沒有遵循,我不會猜測你的意思。請張貼另一個問題,發佈你的表定義('SHOW CREATE TABLE ...'的輸出)和你想運行的查詢。如果您在http://sqlfiddle.com上創建演示,效果會更好。 –