Страница 1 из 1

Поиск в базе. Как оптимизировать.

Добавлено: 08 авг 2012, 11:57
alexei
Есть база на 20 000 строк.
В ней есть поле name (nvarchar) в нем имя игрока, также есть поле онлайн (время последнего захода).

Выполняется запрос:

Код: Выделить всё

SELECT TOP 15 online, vkid, name, level, side, work, win, sex FROM sw.dbo.users WHERE name LIKE @name ORDER BY online DESC;
Где @name=%поисковый запрос%.
Вкратце: ищутся подходящие имена и сортируются по дате захода.
Запрос выполняется около 50мс. Что очень много. Запрос не особо часто выполняется, но достаточно, что бы подумать об оптимизации.


Изображение

Какие варианты есть оптимизировать запрос?

Re: Поиск в базе. Как оптимизировать.

Добавлено: 08 авг 2012, 20:43
Александр
alexei
Для начала сделать индекс столбцу online, если ещё нет. Это ускорит сортировку.
Искать нужно по любой части имени? То есть обязательно выбирать "Алексей" при запросе "лекс"?

Re: Поиск в базе. Как оптимизировать.

Добавлено: 09 авг 2012, 00:06
alexei
Александр писал(а):alexei
Для начала сделать индекс столбцу online, если ещё нет. Это ускорит сортировку.
Искать нужно по любой части имени? То есть обязательно выбирать "Алексей" при запросе "лекс"?
Да. к сожалению так.

Делать индекс по онлайну нерационально. Отсортировать раз в 5 минут 15 пользователей по онлайну это одно. А вот, 5 раз в 1 секунду обновлять онлайн и обновлять индексы это другое. Я думаю, вот это мало что изменит. Нужен другой алгоритм поиска.

Re: Поиск в базе. Как оптимизировать.

Добавлено: 10 авг 2012, 12:47
Александр
Про изменение online что-то и не подумал...

Обычных способов то особо и нет. Тяжелый LIKE или более быстрый, но все равно не подходящий MATCH AGAINST.


Можно попробовать сделать так:

2 таблицы:

search_wordlist
- word_id
- word_text - сочетания букв, по которым может быть поиск

search_wordmatch
- item_id - id пользователя по которому будет поиск
- word_id - id сочетания букв из таблицы search_wordlist, которые встречаются в имени пользователя



Например, искать минимум по 3м буквам:
Имя «Алексей»

search_wordlist

Код: Выделить всё

word_id | word_text1   | але2   | лек3   | екс4   | ксе5   | сей6   | алек7   | лекс...
search_wordmatch

Код: Выделить всё

item_id | word_id1   | 11   | 21   | 31   | 41   | 51   | 61   | 7...
Поиск делать прямым сравнением через равно. Вытащить id искомого word_text из search_wordlist и найти item_id у которого есть связь с этим word_id.

Поиск в phpbb работает по такому принципу, только делит предложения на слова, а не слова на сочетания букв. Объем базы наверно жутко большой будет...

Re: Поиск в базе. Как оптимизировать.

Добавлено: 10 авг 2012, 21:52
alexei
У меня идея такая. Создать отдельное поле в таблице, которое будет переведено в нижний регистр с бинарным поиском. По идеи он более быстрый.

Re: Поиск в базе. Как оптимизировать.

Добавлено: 10 авг 2012, 21:59
alexei
Кстати, имя игрока до 25 символов. Средний 10. Всего около 20 000.
По такой базе я думаю еще дольше искать.


Сделал поле в нижнем регистре с сортировкой Cyrillic_General_BIN . Теперь 9мс, что в 5 раз быстрее.

Re: Поиск в базе. Как оптимизировать.

Добавлено: 10 авг 2012, 22:45
[DIWMS]
Как вариант можно воспользоваться сфинксом ещё

Re: Поиск в базе. Как оптимизировать.

Добавлено: 10 авг 2012, 22:47
alexei
[DIWMS] писал(а):Как вариант можно воспользоваться сфинксом ещё
можно подробнее?