SQL - можно ли это повторно учесть для повышения эффективности? - PullRequest
0 голосов
/ 23 ноября 2011
SELECT
    `Artist`.`id`,
    CONCAT_WS(' ', `Person`.`first_name`, `Person`.`last_name`, `Person`.`post_nominal_letters`) AS `Artist__name`,
    `Portfolio`.`count`,
    `Archive`.`count`,
    `LatestImage`.`id`
FROM
    `people` as `Person`,
    `artists` as `Artist`
LEFT OUTER JOIN
    (SELECT
        `Product`.`artist_id`,
         COUNT(DISTINCT `Product`.`id`) AS `count`
    FROM
        `product_availabilities` AS `ProductAvailability`,
        `products` AS `Product`
    LEFT OUTER JOIN
        `order_details` AS `OrderDetail`
    ON
        `Product`.`id` = `OrderDetail`.`product_id`
    LEFT OUTER JOIN
        `orders` AS `Order`
    ON
        `Order`.`id` = `OrderDetail`.`order_id`
    WHERE
        `ProductAvailability`.`id` = `Product`.`product_availability_id`
    AND
        `Product`.`online` = true
    AND
        (`ProductAvailability`.`name` = 'For sale')
        OR
            ((`ProductAvailability`.`name` = 'Sold') AND (DATEDIFF(now(),`Order`.`order_date`) <= 30))
    GROUP BY
        `Product`.`artist_id`)
AS
    `Portfolio`
ON
    `Artist`.`id` = `Portfolio`.`artist_id`
LEFT OUTER JOIN
    (SELECT
        `Product`.`artist_id`,
         COUNT(DISTINCT `Product`.`id`) AS `count`
    FROM
        `product_availabilities` AS `ProductAvailability`,
        `products` AS `Product`
    LEFT OUTER JOIN
        `order_details` AS `OrderDetail`
    ON
        `Product`.`id` = `OrderDetail`.`product_id`
    LEFT OUTER JOIN
        `orders` AS `Order`
    ON
        `Order`.`id` = `OrderDetail`.`order_id`
    WHERE
        `ProductAvailability`.`id` = `Product`.`product_availability_id`
    AND
        `Product`.`online` = true
    AND
        (`ProductAvailability`.`name` = 'Not for sale')
        OR
            ((`ProductAvailability`.`name` = 'Sold') AND (DATEDIFF(now(),`Order`.`order_date`) >= 30))
    GROUP BY
        `Product`.`artist_id`)
AS
    `Archive`
ON
    `Artist`.`id` = `Archive`.`artist_id`
LEFT OUTER JOIN
    (SELECT
        `Product`.`artist_id`,
        `Product`.`id`
    FROM
        `products` AS `Product`
    WHERE
        `Product`.`online` = true
    ORDER BY
        `Product`.`id` DESC)
AS
    `LatestImage`
ON
    `Artist`.`id` = `LatestImage`.`artist_id`
WHERE
    `Artist`.`person_id` = `Person`.`id`
AND
    `Artist`.`online` = true
GROUP BY
    `Artist`.`id`
ORDER BY
    `Person`.`last_name`, `Person`.`first_name`;

1 Ответ

0 голосов
/ 23 ноября 2011

У вас есть куча избыточности в некоторых запросах.Я создал один подзапрос (ArtistSales), который соединяет продукты с доступностью, а затем с заказами, которые были у вас.Я включаю только элементы «Продажа» или «Продано», но все даты.Используя SUM (IF ()), мы можем выполнить запрос ОДИН РАЗ и получить количество каждого типа (текущий или архив) за один раз.Затем это используется через левое объединение против всех артистов типа "онлайн".Поскольку у меня нет ни MySQL напрямую, ни структур, я буду ждать ваших отзывов о результатах.

SELECT STRAIGHT_JOIN
      A.ID,
      CONCAT_WS(' ', Person.first_name, Person.last_name, Person.post_nominal_letters) AS ArtistName,
      ArtistSales.RecentCount,
      ArtistSales.ArchiveCount,
      MAX( IF( prod.Online, prod.ID, 0 ) LatestImage
   from 
      artists A
         JOIN people as Person
            ON a.Person_ID = Person.ID

         LEFT JOIN Products prod
            ON A.ID = prod.artist_id

         LEFT JOIN
            ( SELECT A2.id,
                     COUNT( DISTINCT P2.ID ) as DistProducts,
                     SUM( IF( DATEDIFF( now(), O.Order_Date ) <= 30, 1, 0 )) RecentCount,
                     SUM( IF( DATEDIFF( now(), O.Order_Date ) > 30, 1, 0 )) ArchiveCount
                 from
                    Artists A2
                       JOIN Products P2
                          on A1.ID = P2.Artist_ID
                          AND P2.Online
                       JOIN product_availabilities AS PAvail
                          ON P2.Product_Availability_ID = PAvail.ID
                             AND PAvail.name IN( 'For sale', 'Sold' )

                       LEFT JOIN order_details AS OD
                          ON P2.ID = OD.Product_ID
                          LEFT JOIN Orders O
                             ON OD.Order_ID = O.ID
                 where
                    A2.Online ) ArtistSales
             ON A.ID = ArtistSales.Artist_ID
   where
      A.Online
   order by 
      Person.Last_Name,
      Person.FirstName
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...