Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте! Имею таблицу mysql которая содержит в себе порядка 200,000 записей. Проблема существует в следующем sql-запросе:
$db_result = mysql_query("SELECT id,url,code FROM ".DB_PREFIX."urls WHERE `url` LIKE '%$last'");
Все хорошо когда запрос отрабатывается разово, но если php выполняет его в цикле, скажем при поиске 300-400 разных $last то процесс поиска может затянуться на несколько минут, при этом до окончания процесса поиска - подвисает сайт.
Задача моего sql-выражения - найти в столбце url все записи, которые оканчиваются на $last.
Столбец url, содержит в каждой записи по одной url-ссылке.
Я использую индексы:
Имя индекса, Тип, Уникальный, Упакован, Столбец, Уникальных элементов, Сравнение, Null
PRIMARY BTREE Да Нет id 191162 A Нет
code BTREE Да Нет code 191162 A Нет
alias BTREE Нет Нет owner 340 A Нет
date_added BTREE Нет Нет date_added 10620 A Нет
url BTREE Нет Нет url 191162 A Нет
Мой my.cnf
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer = 16K
key_buffer_size = 20M
query_cache_size = 10M
innodb_buffer_pool_size = 10M
max_allowed_packet = 4M
table_cache = 40
thread_cache_size = 6
tmp_table_size = 35M
max_heap_table_size = 10M
sort_buffer_size = 512K
read_buffer_size = 256K
read_rnd_buffer_size = 1M
net_buffer_length = 2K
thread_stack = 128K
long_query_time=3
log-slow-queries=/var/log/mysql_long_quarys
log-queries-not-using-indexes
Подскажите, как оптимизировать запрос к БД, что бы избежать "тормозов"?
Неактивен
Индексы не помогут, так как они помогают искать только по начальному куску. Для иллюстрации: возьмите телефонный справочник и найдите в нем всех, у кого фамилия оканчивается на "мян". Придется перебрать всех.
Может помочь только одно - справочник, отсортированный по фамилии, начиная с последней буквы. Как решение можно создать дополнительно к url поле lru, в котором хранить обращенный посимвольно url. В нем уже искать в начале посимвольно обращенный $last. Тогда индекс над lru поможет.
Неактивен
Мм, а полнотекстовый на такой like не поможет?
Неактивен
Полнотекстовый, насколько я знаю, не работает для LIKE, а работает только для MATCH AGAINST
Неактивен
Ну да, я про что-то такое
Неактивен
Это будет скорее тест на наличие слова $last, а не на наличие куска $last (которое может не быть словом) строго в конце текста.
Неактивен
Всем спасибо! Последовал совету и создал дополнительное поле lru и добавил на него индекс. Так же в запросе вместо LIKE теперь использую "=".
Был бы признателен если бы Вы объяснили в чем разница между LIKE и "=".
Отредактированно k0x (06.08.2014 01:44:38)
Неактивен
"=" равенство, в случае строк речь идет о посимвольном совпадении, т.е. 'asd' не равно 'a%'.
LIKE - сравнение по образцу. Можно использовать групповые символы. 'asd' like 'a%' даст совпадение.
http://dev.mysql.com/doc/refman/5.5/en/ … rator_like
P.S. замена LIKE на "=" - плохая идея.
Неактивен
vasya написал:
P.S. замена LIKE на "=" - плохая идея.
Обоснуйте пожалуйста
Неактивен
См предыдущее сообщение. Если у вас задача - найти совпадение по части строки, то "=" не решит задачу.
Неактивен