Главная » 2011 » Май » 31 » Медленные запросы
05:25
Медленные запросы
Привет всем, вот сегодня столкнулся с проблемой при которой мускул может лечь и спать пока его не убют smile
А точнее, некоторые запросы ДЛЕ на довольно мощной машине выходили за пределы 1 секунды. Я стал исследовать mysql.slow-queries.log и наткнулся очень много запросов на выборку похожих новостей.
И вот что мне удалось узнать ...
Я посмотрел как работает это:
Строка show.full.php:
                if( strlen( $row['full_story'] ) < strlen( $row['short_story'] ) ) $body = $row['short_story'];
                else $body = $row['full_story'];
                
                $body = $db->safesql( strip_tags( stripslashes( $metatags['title'] . " " . $body ) ) );
                
                $config['related_number'] = intval( $config['related_number'] );
                if( $config['related_number'] < 1 ) $config['related_number'] = 5;
                
                $db->query( "SELECT id, title, date, category, alt_name, flag FROM " . PREFIX . "_post WHERE MATCH (title, short_story, full_story, xfields) AGAINST ('$body') AND id != " . $row['id'] . " AND approve='1'" . $where_date . " LIMIT " . $config['related_number'] );

Давайте разберемся с тем что мы будем задавать в AGAINST (), $body:
В $body мы получаем Заголовок новости + краткую или полную новость (зависит где меньше текста)
В результате этого не всегда срабатывает функция strlen() (по крайней мере у меня попадаются тексты полных новостей) и мы получаем $body примерно 10КБ (1000 слов).

И так у нас есть что искать, начнем...

В DLE используется полнотекстовый поиск по таким полям (title, short_story, full_story, xfields), если использовать его с текстом в 1000 слов, это сильно грузит мускул.
# Query_time: 2.399032 Lock_time: 0.460428 Rows_sent: 10 Rows_examined: 11 Rows_affected: 0 Rows_read: 11
~2.4 секунды для запроса, я считаю очень много.

по этому я сделал FULLTEXT поиск только для названия новости и краткой новости:
ALTER TABLE `dle_post` DROP INDEX `short_story` ,
ADD FULLTEXT `short_story` (
`short_story` ,
`title`
)

и поменял WHERE MATCH (title, short_story, full_story, xfields)на WHERE MATCH (title, short_story)

Выводы:
Для тех же запросов на нагруженной машине я получал от 0,5 до 50 мс на запрос вместо ~2,4 сек.
С $body я ничего не делал, кому хостер бьет по бошке за нагрузку на БазуДанных рекомендую использовать это:
$body = $db->safesql( strip_tags( stripslashes( $metatags['title'] ) ) );
и удалить это                 if( strlen( $row['full_story'] ) < strlen( $row['short_story'] ) ) $body = $row['short_story'];
                else $body = $row['full_story'];
а также выполнить запрос ALTER TABLE `dle_post` DROP INDEX `short_story` ,
ADD FULLTEXT `short_story` (
`title`
)
Категория: Советы | Просмотров: 480 | Добавил: ALL-DLE | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: