Оптимизировать сложные MySQL выбирает для отчетности - PullRequest
0 голосов
/ 11 апреля 2011

Я создаю приложение, в котором

a) каждый библиотекарь может создать кампанию
b) действия, выполняемые в рамках этой кампании, отслеживаются в campaign_actions, действия - загрузка страницы

Чтобы сообщить о количестве действий, выполненных в каждой кампании, я написал этот SQL-запрос (для MySQL) для следующей структуры базы данных с целью отслеживания количества действийпроводимый библиотекарем для каждой кампании:

LIBRARIANS
id | status

CAMPAIGNS
id | librarian_id

CAMPAIGN_ACTIONS
id | campaign_id | name

Проблемы, с которыми я сталкиваюсь:

a) Я должен указать поля, которые я хочу подсчитать, в соответствующих подвыборах
b) В результате запрос будет довольно дорогим

У меня такой вопрос, поскольку для кампании существует несколько действий, как мне эффективно считать количество действий на * 1020?* более эффективная кампания?

Менее сложные запросы равносильны возврату набора результатов, например:

  librarians.id   |  librarians.status  |  campaign_actions.name
       1                    3                     pageX
       1                    3                     pageY
       1                    3                     pageZ
       1                    3                     pageA
       1                    3                     pageB
       2                    3                     pageX    

, что означает, что мне придется анализировать набор результатов в приложениикод за строкой, которая, вероятно, будет больше дорогой.

Я ценю любые ваши мысли по поводу этой проблемы.

Ответы [ 2 ]

1 голос
/ 12 апреля 2011

Разбиение задачи на более мелкие задачи (представления):

--- campaings per librarian
CREATE VIEW count_librarian_campaigns
AS ( SELECT lib.id AS lib_id
          , COUNT(c.id)
                   AS num_campaigns
     FROM librarians lib
     LEFT JOIN campaigns c
       ON c.librarian_id = lib.id
     GROUP BY lib.id
   )

--- campaign actions per campaign
CREATE VIEW count_campaign_actions
AS ( SELECT c.id   AS c_id
          , COUNT(ca.campaign_id)
                   AS num_actions
     FROM campaigns c
     LEFT JOIN campaign_actions ca
       ON ca.campaign_id = c.id
     GROUP BY c.id
   )

Итак, у вас могут быть такие запросы:

SELECT lib.id AS lib_id
     , countlibc.num_campaigns
     , c.id   AS c_id 
     , countca.num_actions
FROM librarians lib
JOIN count_librarian_campaigns countlibc
  ON countlibc.lib_id = lib.id
LEFT JOIN campaigns c
  ON c.librarian_id = lib.id
JOIN count_campaign_actions countca
  ON countca.c_id = c.id
0 голосов
/ 11 апреля 2011

Работает ли что-то подобное для ваших целей?

SELECT librarians_id,COUNT(librarians_id) FROM (
    SELECT librarians.id as librarians_id,
            librarians.status as librarians_status,
            campaign_actions.name as campaign_actions_name
    FROM campaign_actions
    INNER JOIN campaigns
           ON campaign_actions.campaign_id = campaigns.id
    INNER JOIN librarians
           ON campaigns.librarian_id = librarians.id
    GROUP BY campaign_actions.name,librarians.id,librarians.status ) as a

Может быть, я неправильно понял, что вы ищете.Кажется, что внутренний запрос вернул бы таблицу, которую вы представили выше.

...