Оптимизация sql-запроса

Poster

Новичок
Оптимизация sql-запроса

Господа, плиз взгляните на запрос.

Поясню: один рейс может состоять из двух "саб-рейсов" (туда и обратно), может только из одного

id | abs_id | racenumber | остальные не показаны
-------------------------------
1.......1..........zxc119
2.......1..........zxc120
3.......2..........qwe90
4.......2..........qwe91
9......56.........vbn78


Пока рейсов было мало, достаточно быстро выбирались таким запросом:

PHP:
// цикл по абсолютному номеру abs_id
			   $sqla = "
			   SELECT r.abs_id AS abs_id, r.dateout_p AS dateout_p, r.timeout_p AS timeout_p,
			   r_c.customer_id AS customer_id, d.name AS dname, cus.name AS cusname FROM _races r
			   LEFT JOIN _races_customers_parameters r_c ON (r.abs_id = r_c.abs_id)
			   LEFT JOIN customers cus ON (r_c.customer_id = cus.name)
			   LEFT JOIN directions d ON (r.direction_to_p = d.id)
			   WHERE r.hide = 0
			   GROUP BY r.abs_id
			   ORDER BY $sort_by LIMIT $first, $per_page
			   ";
			   
			   $sql = mysql_query($sqla); echo '<br>'.mysql_error();
			   if (mysql_num_rows($sql)) { $cunter = 0;
				while ($poabsid = mysql_fetch_array($sql)) { $cunter ++;
					// цикл по id рейса
					   $sql2 = mysql_query("SELECT id, abs_id,racenumber,direction_from_p,direction_from_f,
					   TIME_FORMAT(timeout_p, '%H:%i') AS timeout_p,
					   TIME_FORMAT(timeout_f, '%H:%i') AS timeout_f,
					   DATE_FORMAT(dateout_p, '%d.%m.%y') AS dateout_p,
					   DATE_FORMAT(dateout_f, '%d.%m.%Y') AS dateout_f,
					   direction_to_p,direction_to_f,
					   TIME_FORMAT(timein_p, '%H:%i') AS timein_p,
					   TIME_FORMAT(timein_f, '%H:%i') AS timein_f,
					   typevs_p,typevs_f,typevs_c_p,typevs_y_p,
					   pax_c_p,pax_c_f,pax_y_p,pax_y_f,pax_inf_p,pax_inf_f,pax_total_p,pax_total_f,
					   booking_c,booking_y,booking_inf,booking_tot,refuel_ap_out,refuel_ap_in,slot_ap_out,slot_ap_in,	
					   service_ap_out,service_ap_in,
					   paid_wr_ac, tickets_wr_cust, pax_from_cust, trans_pax_ac,
					   comment,changes FROM _races WHERE abs_id = '".$poabsid['abs_id']."' AND hide = 0 ORDER BY id");
						if (mysql_num_rows($sql2)) {
							while ($eachrase = mysql_fetch_array($sql2)) { ?>
И дальше рисуется таблица с выбранными данными.

засекаю время перед запросом
засекаю время после отрисовки таблицы.
4.106 s на 99 рейсов (таблица 198 строк)

В какую сторону двигаться чтобы уменьшить время?

Спасибо
 

Tor

Новичок
в какой таблице у тебя 198 строк?
а в остальных?
индексы присутсвуют?
 

Poster

Новичок
Tor, я неправильно сказал.

Таблица выбранная, отрисованная в хтмл в браузере, с рейсами, 198 строк.

Индексы _races: PRIMARY id
 

SelenIT

IT-лунатик :)
Poster

Ты бы лучше описал, что тебе нужно вывести в итоге (в этой самой 198-строчной таблице) и как хранятся исходные данные. Наверняка это можно сделать без серии запросов в цикле. И время исполнения запроса лучше засекать при "закомментареннном" выводе, иначе объективности не будет никакой.
 

.des.

Поставил пиво кому надо ;-)
Re: Оптимизация sql-запроса

Автор оригинала: Poster
Господа, плиз взгляните на запрос.
[skipped]...
В какую сторону двигаться чтобы уменьшить время?
Спасибо
Двигаться надо по нескольким направлениям.
1. Прочесть правила форума.
2. Выкинуть ненужный код. Оставить только запросы c текстовым пояснением что именно хочется получить.
3. Привести структуру таблиц и индексы.
4. Привести explain http://dev.mysql.com/explain
 

Poster

Новичок
Re: Re: Оптимизация sql-запроса

Вот. Запросом достаются рейсы из таблицы, цель - вывести их на экран и показать пользователю.

Таблица не 198-строчная, просто при показе на странице 99 рейсов (и если каждый из них - "туда и обратно", то есть из двух состоит) рисуется таблица в бравзере 198 строк :)

Записей в таблице _races - пока 594.

Индексты на всех других таблицах -
PRIMARY id


mysql> EXPLAIN _races;
PHP:
+------------------+--------------+------+-----+------------+----------------+
| Field            | Type         | Null | Key | Default    | Extra          |
+------------------+--------------+------+-----+------------+----------------+
| id               | int(6)       |      | PRI | NULL       | auto_increment |
| abs_id           | int(5)       |      | MUL | 0          |                |
| hide             | int(1)       |      |     | 0          |                |
| racenumber       | varchar(9)   |      |     |            |                |
| reg              | int(1)       |      |     | 0          |                |
| direction_from_p | int(5)       |      |     | 4          |                |
| direction_from_f | int(5)       |      |     | 4          |                |
| timeout_p        | time         |      |     | 00:00:00   |                |
| timeout_f        | time         |      |     | 00:00:00   |                |
| dateout_p        | date         |      |     | 0000-00-00 |                |
| dateout_f        | date         |      |     | 0000-00-00 |                |
| direction_to_p   | int(5)       |      |     | 4          |                |
| direction_to_f   | int(5)       |      |     | 4          |                |
| timein_p         | time         |      |     | 00:00:00   |                |
| timein_f         | time         |      |     | 00:00:00   |                |
| typevs_p         | int(5)       |      |     | 0          |                |
| typevs_f         | int(5)       |      |     | 0          |                |
| typevs_c_p       | varchar(255) |      |     |            |                |
| typevs_y_p       | varchar(255) |      |     |            |                |
| typevs_tot_p     | varchar(255) |      |     |            |                |
| typevs_c_f       | varchar(255) |      |     |            |                |
| typevs_y_f       | varchar(255) |      |     |            |                |
| typevs_tot_f     | varchar(255) |      |     |            |                |
| pax_c_p          | int(4)       |      |     | 0          |                |
| pax_c_f          | int(4)       |      |     | 0          |                |
| pax_y_p          | int(4)       |      |     | 0          |                |
| pax_y_f          | int(4)       |      |     | 0          |                |
| pax_inf_p        | int(4)       |      |     | 0          |                |
| pax_inf_f        | int(4)       |      |     | 0          |                |
| pax_total_p      | int(4)       |      |     | 0          |                |
| pax_total_f      | int(4)       |      |     | 0          |                |
| booking_c        | int(5)       |      |     | 0          |                |
| booking_y        | int(5)       |      |     | 0          |                |
| booking_inf      | int(5)       |      |     | 0          |                |
| booking_tot      | int(5)       |      |     | 0          |                |
| refuel_ap_out    | int(1)       |      |     | 0          |                |
| refuel_ap_in     | int(1)       |      |     | 0          |                |
| slot_ap_out      | int(1)       |      |     | 0          |                |
| slot_ap_in       | int(1)       |      |     | 0          |                |
| service_ap_out   | int(1)       |      |     | 0          |                |
| service_ap_in    | int(1)       |      |     | 0          |                |
| inform_valute    | char(1)      |      |     | 0          |                |
| inform_tax_ap    | decimal(7,2) |      |     | 0.00       |                |
| inform_bpc       | decimal(7,2) |      |     | 0.00       |                |
| inform_bpy       | decimal(7,2) |      |     | 0.00       |                |
| inform_ts        | decimal(7,2) |      |     | 0.00       |                |
| inform_cost      | decimal(7,2) |      |     | 0.00       |                |
| paid_wr_ac       | int(1)       |      |     | 1          |                |
| tickets_wr_cust  | int(1)       |      |     | 1          |                |
| pax_from_cust    | int(1)       |      |     | 1          |                |
| trans_pax_ac     | int(1)       |      |     | 1          |                |
| comment          | text         |      |     |            |                |
| changes          | text         |      |     |            |                |
+------------------+--------------+------+-----+------------+----------------+
 

SelenIT

IT-лунатик :)
Сорри, c первого раза проглядел элементранейшую оптимизацию номер раз:
PHP:
...
   $sql = mysql_query($sqla); echo '<br>'.mysql_error();
   $cunter = mysql_num_rows($sql));
   $abs_ids = array();
   while ($poabsid = mysql_fetch_assoc($sql)) {
      $abs_ids[] = $poabsid['abs_id'];
   }
   if ($cunter) {
      $sql2 = mysql_query("SELECT ... WHERE abs_id IN ('".implode("','",$abs_ids)."') AND ... ORDER BY abs_id, id
     ...
Вместо кучи запросов уже имеем только 2.
 

Poster

Новичок
еще Crazy где-то писал, что использование функций в запросе минимизирует смысл использования индексов.

А как же быть с этим?

TIME_FORMAT(timeout_p, '%H:%i') AS timeout_p,
TIME_FORMAT(timeout_f, '%H:%i') AS timeout_f,
DATE_FORMAT(dateout_p, '%d.%m.%y') AS dateout_p,
DATE_FORMAT(dateout_f, '%d.%m.%Y') AS dateout_f,
TIME_FORMAT(timein_p, '%H:%i') AS timein_p,
TIME_FORMAT(timein_f, '%H:%i') AS timein_f,


скриптом разбирать? это правильно?
 

SelenIT

IT-лунатик :)
В данном случае эти поля не используются ни в каких условиях поиска (WHERE и т.п.), поэтому ИМХО тут функции ничему не мешают. Скриптом разбирать (опять же ИМХО) гораздо хуже.
 

Tor

Новичок
Скриптом разбирать (опять же ИМХО) гораздо хуже
это от ситуации зависит
если сервер базы данных и сервер приложений разнесены и первый "занят" значительно больше второго, что имеет смысл сортировать, форматировать скриптом

хотя все-таки правильнее максимум работы класть на базу
 
Сверху