![]() |
Mysql like запросы(+)
Какой порог в плане объема данных(размера таблицы) справедлив для mysql сервера, чтобы получить выборку за приемлемое время.
Запросы в основном типа: select count(*) ... like ... select ... like ... limit ... (т.е. разбивка на страницы) select ... joins ... like ... limit p.s. возникла проблема построения поиска по базе с прайс-листами, полнотекстный поиск заказчика не устраивает. размер таблицы может достигать 100к записей. реально ли использовать like на таких таблицах? или же стоит все-таки отказаться от этой идеи? p.p.s. сервер mysql 3.23.58(freebsd), выделенный сервер. |
Какой справедлив порог ... а какие у тебя данные? Если ты собрался ездить LIKE'ом по полю LONGTEXT, то это одно, а если по VARCHAR, то совсем другое.
Вообще LIKE никогда быстрым не был и использовать его для больших таблиц крайне нежелательно. Мне одно неясно, - каким боком заказчика не устранивает полнотекстовый поиск? |
Ну смотри. Он хочет чтобы было так:
Поле ввода. ввожу «nok», например. Должен быть произведен поиск по всем категориям товаров(обработка логики и т.д.). Ясно, что в «сотовых телефонах» скорее всего будет «nokia», и пользователь должен получить список телефонов и/или других товаров, которые содержат в определенных полях последовательность символов «nok». Кроме того, полнотекстный поиск не ищет(по-умолчанию) слова меньше 4 символов, т.е. тот же телефон «lg» найден не будет. |
hint:
если искать не любые совпадения типа: like "%kwrds%", а свопадения с началом строки, типа: like "kwrds%" да еще и с индексом поиграться, то получается вполне прилично, на таблице со 100к записей результат count будет порядка 0.05-0.06 ms. правда возникает вопрос, как быть если допустим прайс идет типа: "nokia 2600" "nok" он найдет, а вот 2600 уже нет, возможно кнечно кажую позицию сплитить, т.е. table price p_id table split_price sp_id p_id (FK) word но это уже получается полуинддекс:) и придется делать join. вобщем, есть над чем подумать...жду ценных идей и предложений. p.s. random avatars не рулит:( p.p.s. изменения на форуме, я так понимаю — результат работы новой команды разработчиков «форума ИМХО»?:) |
ну кстати fulltext search не такой уж и быстрый. на 110 к записей поиск по часто встречающемуся слову(23к. раз) занимает примерно секунду(или даже больше — точно не помню уже). Это только count.
машинка: athlon xp 1700+ 512 ram ddr mysql 3.23.58 d-max-nt under windows xp sp 2 beta я придумал немного другое решение. но оно пока еще «сыровато». смысл такой: 1. все фразы разбиваем на слова(выкидываем предлоги и прочую муть). 2. записываем в таблицу(примерную структуру я описал выше). 3. создаем индекс(обычный) на поле со словом. 4. ищем только запросами типа like "kwrds%". допустим было: sonyericsson t620 se pid pword 1 sonyericsson 1 t620 1 se запрос будет такой: Код:
SELECT count( * ) нужно сделать вот еще что: каждое слово должно иметь n-представлений, где n=(wordlen-(minSearchWordLen)-1). пример: sonyericsson onyericsson nyericsson yericsson ricsson icsson sson при minSearchWordLen = 4 поиск идет очень быстро, но конечно, если текста очень много данный вариант не пройдет:) хотя последнее можно на любителя, т.к. мало кто не способен написать первые три-четрые буквы того, что ищет. p.s. все вышесказанное относится конечно к специфическому(моему) случаю, когда нужно осуществлять поиск по базе с товарами(по большей части техника). это был поиск в пределах одной записи(прайс-листа). а как сделать поиск типа or — еще проще: Код:
SELECT count( * ) но в новой таблице запрос выполняется за: 0.09 sec. а в старой(это если хранить запись прайс-листа целиком), и тогда запрос будет: Код:
SELECT count( * ) 0.27-0.30 sec. т.е. в 3 раза медленее! |
все-таки решил испробовать задумку с хранением не только отдельных слов, но и частей слов.
вот что получилось: реальный запрос, поиск телефона Samsung d500(точнее подсчет предложений в базе по этому телефону(чтобы было посложнее, я добавил побольше ключевых слов). Код:
SELECT count(distinct sci.str_cat_itm_ID) as cnt FROM store_pword as sw0 inner join store_pword as sw1 on sw0.str_cat_itm_ID = sw1.str_cat_itm_ID inner join store_pword as sw2 on sw1.str_cat_itm_ID = sw2.str_cat_itm_ID inner join store_pword as sw3 on sw2.str_cat_itm_ID = sw3.str_cat_itm_ID inner join store_category_item as sci on sw0.str_cat_itm_ID = sci.str_cat_itm_ID inner join store_category as sc on sci.str_cat_ID = sc.str_cat_ID where sc.str_cat_END_DATE>=1112712382 and sw0.str_PWORD like 'sung%' and sw1.str_PWORD like 'd500%' and sw2.str_PWORD like 'sgh%' 0.14 sec.(запрос помещен в файл и вызывается из консоли). результат: 1000 записей. теперь аналогичный запрос, но поиск обычным like: Код:
SELECT count(sci.str_cat_itm_ID) as cnt FROM store_category_item as sci inner join store_category as sc on sci.str_cat_ID = sc.str_cat_ID where sc.str_cat_END_DATE>=1112712382 and sci.str_cat_itm_TITLE like '%sung%' and sci.str_cat_itm_TITLE like '%d500%' and sci.str_cat_itm_TITLE like '%sgh%' 0.25-0.27 sec. результат: 1000 записей. размеры таблиц: store_category_item: 110.000 store_pword: 657.000 размер минимальной словоформы - 4 символа, т.е. в поиске я еще не ввел это ограничение, но ввел его при индексации, т.е. например: если слово меньше или равно 4, то мы вносим его как есть в таблицу store_pword, если больше 4, тогда: Код:
if ($wordLen >= 3) есть еще идея попробовать полнотекстный поиск по такой таблице и сравнить его с like, но думаю именно такой like будет быстрее. кстати, кто может сказать, что лучше: хранить текст в одной записи, типа: это большой кусок текста (text) или хранить его типа: это (varchar) большой кусок текста при том, что используется полнотекстный индекс и поиск? |
А как сделать запрос, который будет в таблице во всех текстовых полях искать текст.
Вроде так нельзя, но как-нибудь похоже можно, что все поля не перечислять? SELECT * FROM table WHERE * LIKE '%$text%' |
Никак. Либо full-text search либо перечислять. Хотя можно сделать колонку-индекс и искать по ней.
|
В смысле колонку индекс? Отдельную таблицу с словом и его индексом? Запрос разбивать на слова и искать эти слова. Или что-то другое?
А что означает full-text search? |
Часовой пояс GMT +4, время: 12:20. |
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.