Оптимизация запроса mysqli для вычисления медианы с использованием GROUP BY & ORDER BY

0

Ниже приведен пример части моей таблицы MySQL:

имя таблицы: eb_tickets

+-------------------+----------------------+
|  ticket_type      |  time_first_response |
|  Standard Traffic |  0:18:14             |
|  Standard Traffic |  0:48:06             |
|  Miscellaneous    |  44:12:23            |
|  Feed             |  4:48:22             | 
|  Miscellaneous    |  15:33:20            |
|  Banners          |  21:00:02            |
|  Integration      |  36:00:02            |
+-------------------+----------------------+

Я хочу вывести ответ так, вычисляя среднее значение с различными значениями ASC:

+-------------------+----------------------+
|  median_group     |  median              | 
|  Banners          |  21:00:02            |
|  Feed             |  4:48:22             | 
|  Integration      |  36:00:02            |
|  Miscellaneous    |  32:36:13            |
|  Standard Traffic |  0:33:10             |
+-------------------+----------------------+

В настоящее время я достигаю этого со следующим запросом:


    SET @row_number:=0; 
    SET @median_group:='';

    SELECT 
        median_group, AVG(time_first_response) AS median
    FROM
    (SELECT 
        @row_number:=CASE
            WHEN @median_group = ticket_type THEN @row_number + 1
            ELSE 1
        END AS count_of_group,
        @median_group:=ticket_type AS median_group,
        ticket_type,
        time_first_response,
        (SELECT 
                COUNT(*)
            FROM
                eb_tickets
            WHERE
                a.ticket_type = ticket_type) AS total_of_group 
    FROM
        (SELECT 
            ticket_type, time_first_response
        FROM
            eb_tickets           
        ORDER BY ticket_type, time_first_response) AS a) AS b
        WHERE
        count_of_group BETWEEN total_of_group / 2.0 AND total_of_group / 2.0 +1
        GROUP BY median_group

К сожалению, этот запрос занимает около 1 секунды за запись, и я запрашиваю тысячи записей с возможностью использования 20 разных значений для столбца ticket_type.

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

Спасибо за помощь!

Теги:
mysqli

1 ответ

1
Лучший ответ

Не могли бы вы попробовать?

SELECT counter.ticket_type,AVG(time_first_response) AS median FROM
  (
    SELECT 
      IF(@type = type, @ctr := @ctr + 1, @ctr := 1) AS rownum, 
      @type := ticket_type AS ticket_type,
      time_first_response
    FROM eb_tickets
    ORDER BY ticket_type,time_first_response
  ) AS counter,
  (
    SELECT ticket_type, COUNT(*) AS rows
    FROM eb_tickets
    GROUP BY ticket_type
  ) AS types
  WHERE types.ticket_type = counter.ticket_type AND
    CASE rows % 2 
      WHEN 1 THEN rownum IN (ROUND(rows / 2),ROUND(rows / 2))
      ELSE rownum IN (ROUND(rows / 2),ROUND(rows / 2) + 1)
    END
  GROUP BY counter.ticket_type

РЕДАКТИРОВАТЬ:

Первоначально, когда я экспериментировал на SQL, я использовал более короткие имена для type столбцов вместо типа ticket_type а counter подзапросов остался с неправильным type имени столбца вместо ticket_type

  • 0
    Я использовал counter.type вместо counter.ticket_type, потому что я получал ошибку о несуществующем counter.ticket_type, и он возвращает только частичные результаты (хотя результаты верны). Таким образом, он возвращает типы билетов и правильные медианы, однако он не включает в себя все типы билетов в результатах. Было ли изменение counter.ticket_type на counter.type правильным ходом?
  • 0
    Я также отредактировал GROUP BY ticket_type чтобы он был GROUP BY ticket_type,time_first_response и теперь я получаю полный набор результатов с точностью, близкой к моему исходному запросу. Теперь я не уверен, какой запрос является точным: / Однако это сэкономило огромное количество времени в запросе. 118 секунд для 10 записей VS 1 секунда для 10 записей.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню