Как оптимизировать MySQL запрос?

Тема в разделе "Базы данных", создана пользователем Artu, 22 окт 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Artu

    Artu Постоялец

    Регистр.:
    3 мар 2009
    Сообщения:
    75
    Симпатии:
    3
    Код:
    SELECT p.categoryID, p.name, brief_description, customers_rating, Price, in_stock, customer_votes, list_price, productID,default_picture, p.sort_order, items_sold, enabled, product_code, p.description, shipping_freight FROM SS_products p,SS_categories c 
    where
          (  --принадлежность к текущему каталогу
          (0 = 0 and c.sort_order >= 1001)
           or
          (0 <> 0 and c.sort_order < 1001)
          ) and
    
          in_stock<>0 and free_shipping<>1 and
              p.categoryID=c.categoryID and
    
              (
              (00 = 0) --задан ли фильр по бренду
              OR
              productid IN
              (
    
              SELECT
                productid
              FROM
                SS_product_options_values
              WHERE
                option_value = '--Toyota--'
                AND optionID IN
    
                (
                SELECT
                  optionID
                FROM
                  SS_product_options
                WHERE
                  name = 'Brand'
                )
    
              )
              )
    
    --фильтр по возрасту всегда задан       
                      AND
                      productid IN
                      (
                            SELECT
                              o1.productid
                            FROM
                              SS_product_options_values o1,
                              SS_product_options_values o2
                            WHERE
                              o1.productID = o2.productID
                              AND (o1.option_value <> '' OR o2.option_value <> '')
                              AND
    
    
                        ( --Вычисляем входит ли возраст указанный в фильтре в возраст               указанный в товаре с учетом пустых значений
                         (o1.option_value = '' AND (o2.option_value >= 59))
                         or
                         (o2.option_value = '' AND (o1.option_value <= 37))
                         or
                         (o1.option_value <=37 and o2.option_value >=59 )
                         or
                         (o1.option_value >= 37 and o1.option_value <= 59)
                         or
                         (o2.option_value >= 37 and o2.option_value <= 59)
                        )
    
    
                              AND o1.optionID IN
                              (SELECT
                                o.optionID
                              FROM
                                SS_product_options o
                              WHERE
                                o.name = 'Age from')
    
                              AND o2.optionID IN
                              (SELECT
                                o.optionID
                              FROM
                                SS_product_options o
                              WHERE
                                o.name = 'Age to')
                      )
               order by sort_order, name;
    optionID можно задавать константами.Таким образом убрать три подзапроса.

    Больше ничего я не вижу.Все нужно.Может менять порядок операторов,указывать директивы какие-то?
     
  2. koss4u

    koss4u Создатель

    Регистр.:
    20 апр 2009
    Сообщения:
    10
    Симпатии:
    0
    Добавить индексы на все колонны по которым идёт сравнение (name, sort_order, option_value)- хорошее начало оптимизации запроса.

    Если этого не достаточно - можно подумать как избежать IN (SELECT...)
     
  3. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    1) поставить инедксы
    2) изменить структуру базы (добавив новое поле содержащее уже результат условий/я)
    3) разбить сложный запрос, на несколько мелких. Закешировать некоторые из них.
    4) некоторую обработку перевалить на плечи пхп.
     
  4. Laba

    Laba Создатель

    Регистр.:
    27 сен 2009
    Сообщения:
    18
    Симпатии:
    2
    Свяжи два подзапроса

    В исходном запросе два подзапроса один по тойоте, другой по скрещиванию двух выборок. Попробуй эти запросы не через and в основном запросе, а связать между собой по productId.
    Либо так:
    PHP:
    where ...
    (
              
    SELECT
                productid
              FROM
                SS_product_options_values
              WHERE
                option_value 
    '--Toyota--'
     
    ....
    )
    IN 
    (
      
    SELECT o1.productid
       FROM
             SS_product_options_values o1
    ,
             
    SS_product_options_values o2
       
    ....
    )
    Либо так:
    PHP:
    (
      
    SELECT o1.productid
       FROM
             SS_product_options_values o1
    ,
             
    SS_product_options_values o2
       WHREE 
         o1
    .productID IN
          
    (
              
    SELECT
                productid
              FROM
                SS_product_options_values
              WHERE
                option_value 
    '--Toyota--'
     
    ....
               )
       ....
    )
     
Статус темы:
Закрыта.