Как оптимизировать запрос к базе данных MySQL?

12 3
[Удален]
959

Всем привет.

Есть некая база MySQL, а в ней нужная таблица весом 400 кб и 2500 записей.

К этой таблице идет запрос "SELECT поле1, поле2, поле3, поле4 FROM наша_таблица WHERE a>100 AND a<1000 ORDER BY дата DESC".

Результат - все 2500 строк (но это только в этом случае, могут быть случаи, когда не все строки уходят в результат). На сам запрос и перебор всех строк уходит порядка 18 секунд (проверил через пхп, из которого идет запрос).

Вопрос следующий: возможно ли ка-то уменьшить это время с помощью добавления индексов в талицу, или какими-то другими методами?

Добавить LIMIT в запрос не предлагайте: нужны все данные и сразу.

IL
На сайте с 20.04.2007
Offline
435
#1

Добавить индекс по полю a + data

... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#2

Какая-то аномалия(при условии что у Вас сервер нормально дышит и не 500лохматых годов, где 1мб оперативы - мечта) получается.

Можно дамп базы в студию? Ну и код ПХПшный, который все это обрабатывает тоже желательно бы увидеть.

Подпись))
IL
На сайте с 20.04.2007
Offline
435
#3
Милованов Ю.С:
Какая-то аномалия

Может там перебор "хитрый" :D

А вообще, интересно, если этот же запрос засунуть в PHPMyAdmin - время изменится? ))

[Удален]
#4
Милованов Ю.С:
Какая-то аномалия(при условии что у Вас сервер нормально дышит и не 500лохматых годов, где 1мб оперативы - мечта) получается.
Можно дамп базы в студию? Ну и код ПХПшный, который все это обрабатывает тоже желательно бы увидеть.

Сервер вроде норм: 2 проца по 6 ядер 1,6 Ггц каждое, 32 Гб ОЗУ.

Извините, базу предоставить не могу: внутренняя информация компании.

$row=$db->query( "");
while ( $row = $db->get_row() ) {

}

class db {
function query($query, $show_error=true)
{
$time_before = $this->get_real_time();

if(!$this->db_id) $this->connect(DBUSER, DBPASS, DBNAME, DBHOST);

if(!($this->query_id = mysqli_query($this->db_id, $query) )) {

$this->mysql_error = mysqli_error($this->db_id);
$this->mysql_error_num = mysqli_errno($this->db_id);

if($show_error) {
$this->display_error($this->mysql_error, $this->mysql_error_num, $query);
}
}

$this->MySQL_time_taken += $this->get_real_time() - $time_before;

$this->query_num ++;

return $this->query_id;
}
function get_row($query_id = '')
{
if ($query_id == '') $query_id = $this->query_id;

return mysqli_fetch_assoc($query_id);
}


}
ivan-lev:
Может там перебор "хитрый" :D

А вообще, интересно, если этот же запрос засунуть в PHPMyAdmin - время изменится? ))

Пробывал в PHPMyAdmin - >15 секунд

П.С. не смог сделать чтобы Limit не вставлялся в запрос, поэтому добавил к запросу LIMIT 0,2600

---------- Добавлено 10.12.2013 в 18:19 ----------

ivan-lev:
Может там перебор "хитрый" :D

А вообще, интересно, если этот же запрос засунуть в PHPMyAdmin - время изменится? ))

Добавил INDEX по полу "а" и "дата" повторил запрос в PHPMyAdmin - Запрос занял 0.0015 сек., но через браузер никаких изменений.

A1
На сайте с 04.09.2013
Offline
18
#5
Mr.Boba:
К этой таблице идет запрос "SELECT поле1, поле2, поле3, поле4 FROM наша_таблица WHERE a>100 AND a<1000 ORDER BY дата DESC".
...
Вопрос следующий: возможно ли ка-то уменьшить это время с помощью добавления индексов в талицу, или какими-то другими методами?

Для таблиц типа MyISAM можно попробовать сделать coverage индекс типа:

CREATE INDEX `ix_наша_таблица` ON `наша_таблица` (`a`, `дата` DESC, `поле1`, `поле2`, `поле3`, `поле4`);

После чего проверить значение переменной key_buffer_size в my.cnf (выделенного количества памяти в идеале должно хватать для хранения всех индексов MyISAM, значения по умолчанию должно более чем хватить для одной базы в 400KB).

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


SET profiling = 1;
SELECT поле1, поле2, поле3, поле4 ...
SHOW PROFILE FOR QUERY 1;
IL
На сайте с 20.04.2007
Offline
435
#6
Mr.Boba:
Пробывал в PHPMyAdmin - >15 секунд

Значит дело не в запросе.

Ваш КО

Mr.Boba:
На сам запрос и перебор всех строк уходит порядка 18 секунд (проверил через пхп, из которого идет запрос).

Смотрите внимательнее, что там за "перебор"

siv1987
На сайте с 02.04.2009
Offline
427
#7
Mr.Boba:
class db {

А нафига нам этот класс? судя по всему это кусок кода с ДЛЕ.

abbat13:
Для таблиц типа MyISAM можно попробовать сделать coverage индекс типа:

Покрывающие индексы можно делать мне кажется и не только на myisam, но в данном случае это будет слишком избыточный индекс.

Mr.Boba:
Добавил INDEX по полу "а" и "дата" повторил запрос в PHPMyAdmin - Запрос занял 0.0015 сек., но через браузер никаких изменений.

ковыряйте фетчинг вашего запроса, если там результат на 2500 строк, то за 0.0015 сек они конечно не обработаются

IL
На сайте с 20.04.2007
Offline
435
#8
siv1987:
если там результат на 2500 строк, то за 0.0015 сек они конечно не обработаются

Это понятно, однако, 18 секунд тоже многовато.. Разве что, там ресурсоёмкая хрень какая считается..

[Удален]
#9
abbat13:


SET profiling = 1;
SELECT поле1, поле2, поле3, поле4 ...
SHOW PROFILE FOR QUERY 1;

И где смотреть результат этого запроса? Ато у меня постоянно отвечает:

"SQL-запрос был успешно выполнен

SHOW PROFILE FOR QUERY1"

и внизу мой запрос и ответ на него

iputin
На сайте с 26.11.2013
Offline
4
#10

Mr.Boba, еси работаете на localhost то попробуйте получить вот такую переменную

$sqlQ = mysql_query("show status like '%Questions%'");
$sqlN = mysql_num_rows($sqlQ);
$sq = 0;
while ($sq < $sqlN) {
$sq++;
$sql = mysql_fetch_assoc($sqlQ);
print 'Запросов ' . $sql['Variable_name'] . ': ' . $sql['Value'];
}

у меня возники сомнения что запрос у вас в данном сучае всего 1

а вообще я юзаю счетчики в купе со временем генерации и подсчетом испоьзованной памяти может там ответ найдете

12 3

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий