1 Востаннє редагувалося ozimok (22.10.2013 13:39:56)

Тема: допоможіть з аналізом запиту до MySQL

Для ясності - я не програміст (3 роки юридичної практики), тому сподіваюсь на конструктивну критику.
В процесі створення проекту виникла необхідність виконувати такий запит:

SELECT tour_name, tour_variant_price, 

GROUP_CONCAT( DISTINCT exp_travel_tour_date.tour_date_date ORDER BY tour_date_date ASC ) AS tour_dates

FROM exp_travel_tours
  LEFT JOIN exp_travel_tour_date ON tour_id = tour_date_tour_id
  LEFT JOIN exp_travel_tour_variants ON ( tour_id = tour_variant_tour_id

  AND tour_variant_price = ( 
    SELECT MIN( tour_variant_price ) 
    FROM exp_travel_tour_variants
    WHERE tour_id = tour_variant_tour_id )
  ) 

WHERE tour_date_date > "2013-10-10"

GROUP BY exp_travel_tours.tour_id

ORDER BY tour_variant_price DESC 

LIMIT 10

[b]Тестовий результат вибоки:[/b]

array(2) {
  [0]=>
  array(3) {
    ["tour_name"]=>
    string(6) "Тур"
    ["tour_variant_price"]=>
    string(3) "180"
    ["tour_dates"]=>
    string(65) "2013-10-14,2013-10-15,2013-10-16,2013-10-17,2013-10-18,2013-10-19"
  }
  [1]=>
  array(3) {
    ["tour_name"]=>
    string(8) "тур 2"
    ["tour_variant_price"]=>
    NULL
    ["tour_dates"]=>
    string(43) "2013-10-22,2013-10-23,2013-10-24,2013-10-25"
  }
}

В таблиці буде  <= 5000 записів, навантаження на проект  максимально 10 запитів в секунду.

Питання: наскільки поганий цей запит?

2

Re: допоможіть з аналізом запиту до MySQL

Нічого принципово поганого я в цьому коді не бачу. Перевірте, чи проіндексовані поля, за якими здійснюються сортування, пошук мінімуму і т.д.
А на питання про навантаження вам може тільки сервер відповісти, ми ж не знаємо, на чому ви його виконуєте.

3

Re: допоможіть з аналізом запиту до MySQL

ТС, на замітку: не обов'язково створювати тему двічі у різних розділах: за необхідності модератори можуть її перемістити до відповідного розділу. :)

4

Re: допоможіть з аналізом запиту до MySQL

koala написав:

Нічого принципово поганого я в цьому коді не бачу. Перевірте, чи проіндексовані поля, за якими здійснюються сортування, пошук мінімуму і т.д.
А на питання про навантаження вам може тільки сервер відповісти, ми ж не знаємо, на чому ви його виконуєте.

Дякую за відповідь, навантаження мене цікавило більше з точки зору складності запиту і використання GROUP_CONCAT(). З індексами все гуд.

5

Re: допоможіть з аналізом запиту до MySQL

Ні, ну запит складний, але ж неможливо робити складні речі просто, еге ж?

6 Востаннє редагувалося ozimok (22.10.2013 16:51:00)

Re: допоможіть з аналізом запиту до MySQL

Що правда то правда, ось кінцевий варінт запиту:

SELECT 
    tour_id,
    tour_name,
    tour_length, 
    tour_currency_id,

    GROUP_CONCAT(DISTINCT tour_date_date ORDER BY tour_date_date ASC) AS tour_dates,
    
    GROUP_CONCAT(DISTINCT city_name SEPARATOR " / ") AS tour_cities,
    
    GROUP_CONCAT(DISTINCT transport_name) AS tour_transport,
    
    tour_variant_price, 
    tour_variant_price_old,
    
    rate.exchange_rate_value AS exchange_rate,
    
    rate_default.exchange_rate_value AS exchange_rate_default
    
FROM '.$this->db->dbprefix('tours').'

LEFT JOIN '.$this->db->dbprefix('tour_date').' 
    ON tour_id = tour_date_tour_id
    
LEFT JOIN '.$this->db->dbprefix('tour_city').' 
    ON tour_id = tour_city_tour_id
    
LEFT JOIN '.$this->db->dbprefix('cities').' 
    ON tour_city_city_id = city_id
    
LEFT JOIN '.$this->db->dbprefix('tour_transport').' 
    ON tour_id = tour_transport_tour_id
    
LEFT JOIN '.$this->db->dbprefix('transport').' 
    ON tour_transport_transport_id = transport_id
        
LEFT JOIN '.$this->db->dbprefix('exchange_rates').' rate 
    ON tour_partner_id = exchange_rate_partner_id
        AND exchange_rate_cy_id = tour_currency_id

LEFT JOIN '.$this->db->dbprefix('exchange_rates').' rate_default 
    ON rate_default.exchange_rate_partner_id = 0
        AND rate_default.exchange_rate_cy_id = tour_currency_id 

LEFT JOIN '.$this->db->dbprefix('tour_variants').' 
    ON (tour_id = tour_variant_tour_id
        
        AND tour_variant_price = (
            SELECT MIN(tour_variant_price) 
            FROM '.$this->db->dbprefix('tour_variants').' 
            WHERE tour_id = tour_variant_tour_id
        )
        
    )

WHERE tour_date_date > "2012-10-10"

GROUP BY tour_id

ORDER BY tour_variant_price DESC, tour_city_id ASC

LIMIT 10

Питання вирішено, шляхом створення view

7

Re: допоможіть з аналізом запиту до MySQL

шановний ТС, прочитайте, будь ласка, оце та пощадіть наші очі виконайте відповідні дії

8

Re: допоможіть з аналізом запиту до MySQL

Grammar Nazi mode on

Панно Cyan, заходи вживаються, а не робляться.

9

Re: допоможіть з аналізом запиту до MySQL

2koala

та, дякую, мені теж здалось, що трохи "не звучить"
виправила, але не так, як очікувалось

Подякували: koala1

10 Востаннє редагувалося ozimok (22.10.2013 16:51:14)

Re: допоможіть з аналізом запиту до MySQL

Вибачте, за відсутність хайлайту коду, виправив.
Питання вирішено, шляхом створення view

11

Re: допоможіть з аналізом запиту до MySQL

П.С. Хоча питання вирішено, між іншим побачив не дуже оптимізований код:

AND tour_variant_price = (
            SELECT MIN(tour_variant_price) 
            FROM '.$this->db->dbprefix('tour_variants').' 
            WHERE tour_id = tour_variant_tour_id
        )

Тут для кожного рядка з полем tour_variant_price буде робитись по одному запиту до таблиці $this->db->dbprefix('tour_variants')...

12

Re: допоможіть з аналізом запиту до MySQL

ozimok написав:

Питання: наскільки поганий цей запит?

на стільки, на скільки може бути поганим запит до мускула)