Статистика

Участников проекта 105
Опубликовано статей 78
Отчет по карме. Топ 20

Новости блога

1 29.11.2013  Сегодня самым активным участникам newblog'а был выплачен доход с sape.
7 02.11.2012  Ура! Свешилось, нашему сайту дали тИЦ 10. Спасибо всем кто принимает участие в развитии нашего блога.
8 21.08.2012  Интеграция с sape.ru. Теперь каждый автор статей на newblog автоматически зарабатывает на рекламе.
Все новости

Топ 5 категорий

Программирование 46
Операционные системы 9
Базы данных 4
Туризм 2
Заметки 2

Последние 5 заметок (90)

gullyar - Закладки gullyar
gullyar - Ваша первая закладка
osadchaya - Закладки osadchaya
Ira0231188 - Закладки Ira0231188
Ira0231188 - Закладки Ira0231188

Ссылки

www.freedev.asia

Методы оптимизации запросов в MySQL (часть 2)

20.09.2012 08:40 | Просмотров: 3614 | Доход: 68.09 руб. | Комментариев: 1
[Базы данных] 
Рейтинг: 4.8/5

При разработке HighLoad систем даже самые простые запросы могут повлиять на производительность в целом. В предыдущей статье по mysql  я уже рассказывал про замечательный инструмент explain который позволяет оптимизировать запросы. Но порой даже в крупных проектах встречаются простые ошибки, которые могут привести к значительному снижению производительности. Если приходится оптимизировать чужой код, следующая информация может пригодиться.

1. limit.
Нарпример не обдуманное использование limit встречается очень часто в различных проектах. При пагинации больших таблиц частой ошибкой является использование "limit x,y". В больших таблицах данные как правило не удаляются а деактуализируются, не нарушая последовательность инкрементного поля.

$start = microtime(true);
$query = "SELECT * from table limit 10000000,5";
$data = mysql_query($query);
$time = microtime(true) - $start;
echo $time; //18.894818067551


Многовато, верно?
 

$start = microtime(true);
$query = "SELECT * from table where id between 10000000 and 10000005";
$data = mysql_query($query);
$time = microtime(true) - $start;
echo $time; //0.00034213066101074


Так гораздо быстрее. Правдо тут есть одно "но", как я уже сказал id должны идти по порядку. Это желательно учитывать при разработке архитектуры базы данных. Также можно в качестве интервала использовать определенный временной период времени. А если вам нужно перебрать поблочно все 10 млн записей - тут и говорить нечего.

2. Tree
Довольно часто в серьезных проектах приходится хранить иерархические данные в таблицах. Например это могут быть разделы с неограниченным количеством подразделов. При сложных уровнях часто используют МРТТ логику для построения иерархии. Приведу небольшой пример для наглядности.

name/lft/rght
Департамент ИС/1/12
  Отдел программирования/2/7
    Иванов/3/4
    Петров/5/6
  Отдел сопровождения/8/11
    Сидоров/9/10

Если записей в таблице сотни тысяч и необходимо найти все дочерние элементы для какого-либо узла с учетом вложенности, то можно легко допустить ошибку:
 

mysql> SELECT count(*) from table where lft > 1000000 and rght < 1000100;
+----------+
| count(*) |
+----------+
|       48 |
+----------+
1 row in set (1.88 sec)



При больших таблицах эта ошибка может повлечь за собой сильное "торможение" запросов. Причем на практике выявить данную ошибку достаточно сложно. А происходит это из-за того, что движок mysql вынужден пробежать все записи, так как диапазон lft не ограничен сверху, а rght - снизу. Что хорошо видно при использовании explain.
Правильнее использовать следующий запрос:
 

mysql> SELECT count(*) from table where lft between 1000000 and 1000100 and rght between 1000000 and 1000100;
+----------+
| count(*) |
+----------+
|       48 |
+----------+
1 row in set (0.0014 sec)



Ну вот и все, надеюсь кому-нибудь пригодятся эти два простых совета и они не допустят таких ошибок.
 


© GM
| Комментировать статью |
  • Аноним 0 (28.11.2013 19:21)
    Я оптимизирую SELECT COUNT с помощью MongoDB...
    | Ответить |