Болд
Guest
Пересечение множеств
Здравствуйте!
Есть следующая структура по поиску информации на сайте: все страницы парсятся - убираются комментарии, тэги и прочее. Потом каждая страница разбивается на слова.
В БД есть две таблицы: одна со словами и их id, вторая с id слов и id страниц, на которых они встретились.
таблицы:
create table words (word_id integer primary key, word varchar 255);
create table indexes (word_id integer, page_id integer);
Пример заполнения,
words
---------------------
word | word_id
---------------------
привет | 1
пока | 2
понедельник | 3
суббота | 4
indexes
-----------------
word_id | page_id
-----------------
1 | 1
1 | 2
2 | 2
2 | 3
3 | 1
3 | 3
3 | 4
4 | 2
4 | 4
Вопрос: как выбрать все страницы, на которых встретились нужные слова? Для одного слова все решается просто:
[sql]
SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово%' AND words.word_id=indexes.word_id;
[/sql]
А для нескольких слов? Оператор OR возращает объединение - т.е. все страницы, на которых встретилось ХОТЬ ОДНО слово, а надо, чтобы только ВСЕ слова.
Решение через IN ('слово1', 'слово2') лишает прелести like 'слово%' - так решаются проблемы с окончаниями и прочие радости.
Сейчас работает через INTERSECT. Например,
[sql]
SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово%' AND words.word_id=indexes.word_id INTERSECT SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово2%' AND words.word_id=indexes.word_id;
[/sql]
Проблема: скорость выполнения (плюс intersect не работает в mysql). При 5, 6 и т.д. слов в запросе, время выполнения быстро растет. Нужны доли секунд, а при 5 словах уже приближается к секунде. Подскажите приемлимое решение, пожалуйста!
Здравствуйте!
Есть следующая структура по поиску информации на сайте: все страницы парсятся - убираются комментарии, тэги и прочее. Потом каждая страница разбивается на слова.
В БД есть две таблицы: одна со словами и их id, вторая с id слов и id страниц, на которых они встретились.
таблицы:
create table words (word_id integer primary key, word varchar 255);
create table indexes (word_id integer, page_id integer);
Пример заполнения,
words
---------------------
word | word_id
---------------------
привет | 1
пока | 2
понедельник | 3
суббота | 4
indexes
-----------------
word_id | page_id
-----------------
1 | 1
1 | 2
2 | 2
2 | 3
3 | 1
3 | 3
3 | 4
4 | 2
4 | 4
Вопрос: как выбрать все страницы, на которых встретились нужные слова? Для одного слова все решается просто:
[sql]
SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово%' AND words.word_id=indexes.word_id;
[/sql]
А для нескольких слов? Оператор OR возращает объединение - т.е. все страницы, на которых встретилось ХОТЬ ОДНО слово, а надо, чтобы только ВСЕ слова.
Решение через IN ('слово1', 'слово2') лишает прелести like 'слово%' - так решаются проблемы с окончаниями и прочие радости.
Сейчас работает через INTERSECT. Например,
[sql]
SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово%' AND words.word_id=indexes.word_id INTERSECT SELECT DISTINCT indexes.page_id FROM indexes, words WHERE words.word_id LIKE 'слово2%' AND words.word_id=indexes.word_id;
[/sql]
Проблема: скорость выполнения (плюс intersect не работает в mysql). При 5, 6 и т.д. слов в запросе, время выполнения быстро растет. Нужны доли секунд, а при 5 словах уже приближается к секунде. Подскажите приемлимое решение, пожалуйста!