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

Статус
В этой теме нельзя размещать новые ответы.

Artu

Постоялец
Регистрация
3 Мар 2009
Сообщения
75
Реакции
2
Код:
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 можно задавать константами.Таким образом убрать три подзапроса.

Больше ничего я не вижу.Все нужно.Может менять порядок операторов,указывать директивы какие-то?
 
Добавить индексы на все колонны по которым идёт сравнение (name, sort_order, option_value)- хорошее начало оптимизации запроса.

Если этого не достаточно - можно подумать как избежать IN (SELECT...)
 
1) поставить инедксы
2) изменить структуру базы (добавив новое поле содержащее уже результат условий/я)
3) разбить сложный запрос, на несколько мелких. Закешировать некоторые из них.
4) некоторую обработку перевалить на плечи пхп.
 
Свяжи два подзапроса

В исходном запросе два подзапроса один по тойоте, другой по скрещиванию двух выборок. Попробуй эти запросы не через 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--'
 ....
           )
   ....
)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху