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

  • Автор темы Автор темы Poster
  • Дата начала Дата начала

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 строк)

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

Спасибо
 
в какой таблице у тебя 198 строк?
а в остальных?
индексы присутсвуют?
 
Tor, я неправильно сказал.

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

Индексы _races: PRIMARY id
 
Poster

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

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


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

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