|
|
|
| Доброго времени суток, пишу страницу которая выводит следующие данные:
Исполнитель (имя), его альбомы (с годами), стиль, жанр, похожие артисты
другая страница с альбомом этого исполнителя:
Исполнитель (имя), Название альбома, всего времени в альбоме, список песен, жанр, стиль, похожие артисты
Структура таблиц (дамп, и их вид) представлены во вложенном файле.
На основании скипрта который тут приводили, сделал немного другой и с помощью него смотрю скорость обработки запросов:
<?php
function gettime()
{
$part_time = explode(' ', microtime());
$realtime = $part_time[1].substr($part_time[0],1);
return $realtime;
}
$id_singer = '79';
$id_album = '';
$id_style = '45';
$sql[] = "SELECT DISTINCT(file.id_genre),name_genre FROM file LEFT JOIN genre ON file.id_genre=genre.id_genre WHERE id_singer='$id_singer';";
$sql[] = "SELECT DISTINCT(file.id_style),name_style FROM file LEFT JOIN style ON file.id_style=style.id_style WHERE id_singer='$id_singer';";
$sql[] = "SELECT DISTINCT(file.id_singer),singer.name_singer FROM file LEFT JOIN singer ON file.id_singer=singer.id_singer WHERE id_style='$id_style' ORDER BY RAND() LIMIT 20;";
mysql_connect('localhost','root','8520');
mysql_select_db('music');
$start_time = gettime();
$indexLimit = count($sql);
for ($index=0; $index < $indexLimit; $index++) {
mysql_query($sql[$index]);
}
$stop_time = gettime();
$total = bcsub($stop_time, $start_time, 2);
print "Execution time: ".$total;
?>
|
есть еще другие запросы, но их время выполнения 0.02, если добавить эти три, то время выполнения возрастает до 1.04 секунды.
Этими запросам выбирается:
1) id жанра, название жанра - (0.32)
2) id стиля, название стиля (0.34)
3) id исполнителя, имя исполнителя (0.34)
Подскажите, можно ли постоить запросы как нибудь по другому чтобы сократить время их выполнения? | |
|
|
|
|
|
|
|
для: Unreal
(09.01.2007 в 03:56)
| | Такая скорость на сервере или на локальной машине? | |
|
|
|
|
|
|
|
для: cheops
(09.01.2007 в 12:46)
| | локальный компьютер, Core Duo 2 итд, возможно проблема в неверном проектировании таблиц или числе записей в них?
Число записей по таблицам:
album - 39945
file - 468977
genre - 18
singer - 11684
style - 342 | |
|
|
|
|
|
|
|
для: Unreal
(09.01.2007 в 12:53)
| | Тогда всё нормально... MySQL не настраивали, сколько Мб под неё выделено? Жёсткий диск IDE или SATA - шина на материнской плате одна? Компьютер регулярно выключаете? В результате кэши индексов и запросов (даже такие маленькие, которые выделены по умолчанию) постоянно обнуляются...
Нужно тестировать на рабочем сервере, локальная машина, даже очень мощная - это не показатель... MySQL расчитана на большую нагрузку. У меня дома этот форум по минуте открывается, хотя машина не слабая и только под MySQL выделено пол-гигабайта памяти. Но так как посетителей нет - кэши не заполнены и производительность хуже некуда. | |
|
|
|
|
|
|
|
для: cheops
(09.01.2007 в 13:06)
| | У хостера тоже самое, проблема в том что страниц много (например по тем же исполнителям 11684) и все они разные, выборка совершенно разная будет и врятле там что-то скешируется, потому что shared hosting, серваки у хостера мощные, но много разных запросов идет от разных сайтов .
Пробовал специально взять Apache Bench и запустить его на одну и ту же страницу (на домашнем компе), для начала поставил 100 запросов к странице, действительно у MySQL hitrate поднялся почти до 100%. Это было бы приемлимо если бы эту страницу постоянно грузили, но как я писал выше, для каждого исполнителя создается новая страница.
Диск Seagate Barracuda 10000 rpm SATA, 1 Gb памяти, винда ставилась недавно, всякими экспериментами с софтом не занимаюсь, глюкавые програмки не ставлю, работаю админом, так что дома на эксперименты не тянет :) MySQL действительно был запущен с дефолтным конфигом по той причине что хотел написать приложение быстрое, а не надеятся на скорость компа.
Сейчас запустил MySQL с конфигом my-huge.ini по всем запросам Query Cache Hitrate взлетел до 100%, Key Efficience - 100%, скорость отдачи страниц в Apache Bench естественно поднялась кроме вот этого запроса:
<?php
$sql[] = "SELECT DISTINCT(file.id_singer),singer.name_singer FROM file LEFT JOIN singer ON file.id_singer=singer.id_singer WHERE id_style='$id_style' ORDER BY RAND() LIMIT 20;";
?>
| хотя оно и понятно, т.к. в нем ORDER BY RAND
Приложил файл с небольшим дампом с данными, в нем данные по одному исполнителю.
UPD:
cheops, вы правы насчет скорости загрузки, она действительно очень возрастает при загрузке одной и той же страницы (в моем случае получается по одним запросам). Попробовал сейчас убрать ORDER BY RAND() и снова натравить Apache Bench, скорость загрузки страниц со всеми 8ю запросами выросла до 48ms. Просто я думал что может это я запросы неправильно строю, и поэтому так медленно все работает. Хотелось бы выжать все что можно из MySQL при помощи оптимизации запросов или изменения структуры таблиц не принимая во внимание кэширование запросов... | |
|
|
|
|
|
|
|
для: Unreal
(09.01.2007 в 03:56)
| | а индексы по полям с id_ами построены?
DISTINCT - вообще злая вещь.... | |
|
|
|
|
|
|
|
для: Trianon
(09.01.2007 в 13:14)
| | да, индексы есть, но это не помогает в данном случае. Возможно индексы не на тех полях стоят
в первом сообщении аттач, там таблицы в виде картинок с помощью символов представлены | |
|
|
|
|
|
|
|
для: Unreal
(09.01.2007 в 13:46)
| | В аттаче первого сообщения дамп структуры. И индексов, кроме первичных, там таки невидно. | |
|
|
|
|
|
|
|
для: Trianon
(09.01.2007 в 14:42)
| | Я не очень разбираюсь в этом, знаю только что если на строке стоит Primary Key то она выбирается быстрее. Подскажите что тогда можно изменить в этих таблицах? | |
|
|
|
|
|
|
|
для: Unreal
(09.01.2007 в 15:13)
| | Создать индексы на остальных id_... полях
например, у таблицы file, помимо первичного ключа id_file (индекс для которого уже создан автоматически) нужно создать индексы для полей id_singer, id_album, id_style,id_genre, по сути своей представляющих чужие ключи.
ALTER TABLE `file` ADD INDEX ( `id_singer` );
ALTER TABLE `file` ADD INDEX ( `id_album` );
ALTER TABLE `file` ADD INDEX ( `id_style` );
ALTER TABLE `file` ADD INDEX ( `id_genre` );
|
Так же и с другими таблицами. | |
|
|
|
|
|
|
|
для: Trianon
(09.01.2007 в 15:42)
| | Огромное спасибо :-)
Ваш совет действительно помог, даже с дефолтным конфигом от MySQL все 8 запросов выполняются за 0.10 сек | |
|
|
|