2013-08-31 2 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, Я согласен с вами для обоих предложений, но Предположим, у меня есть два увлечения, такие как прослушивание музыки, прослушивание песен. и мое требование только передает ключевое слово 'listen' в where where и если я не использую mYISAM. то то, что я должен сделать для обоих, - это слушать музыку и слушать песни? –

+0

Я не последовал этому, и я не собираюсь догадываться, что вы имеете в виду. Отправьте еще один вопрос, разместите свои определения таблиц (вывод 'SHOW CREATE TABLE ...') и запрос, который вы хотите запустить. Еще лучше, если вы создадите демо на http://sqlfiddle.com. –

Смежные вопросы