подзапросы по оптимизации той же таблицы - PullRequest
0 голосов
/ 01 мая 2019

Я работаю над проектом статистического отчета, чтобы показать наибольшее количество поисковых запросов, в таблице около 50 млн записей.

Таблица (упрощенная):

+----------------------+--------------+
| Field                | Type         |
+----------------------+--------------+
| acct                 | varchar(5)   |
| branch               | varchar(2)   |
| page_name            | varchar(20)  |
| access_time          | datetime     |
| query_input          | varchar(500) |
+----------------------+--------------+

page_name может быть 3 значения: 'search' 'detail' или 'cart'

Мне нужен каждый тип page_name, сгруппированный по query_input и подсчитывающий строки в порядке убывания с ограничениями в пределах одного запроса. сначала я просто позволяю hibernate получить все записи, а затем обработать их в java, но запрос занимает слишком много времени, хотя я использую сеанс без сохранения состояния.

Чтобы уменьшить размер данных, возвращаемых из спящего режима, я попробовал это

(SELECT page_name, query_input, count(*) FROM table_name WHERE acct='XXXXX' AND page_name='search 'GROUP BY query_input ORDER BY COUNT(*) DESC LIMIT 100)
UNION ALL
(SELECT ... AND page_name='detail' ...)
UNION ALL
(SELECT ... AND page_name='cart' ...)

но это приведет к тому, что база данных будет циклически повторять таблицу 3 раза, есть ли способ перефразировать запрос, чтобы он только зацикливал таблицу один раз, но получал тот же результат, что и я?

Например, без ограничений:

+----------------------+--------------+---------+
| page_name            | query_input  | count(*)|
+----------------------+--------------+---------+
| search               | CCC          | 10      |
| search               | EEE          | 8       |
| search               | AAA          | 1       |
| search               | BBB          | 1       |
| detail               | DDD          | 12      |
| detail               | FFF          | 11      |
| detail               | HHH          | 1       |
| detail               | GGG          | 1       |
| cart                 | III          | 6       |
| cart                 | JJJ          | 4       |
| cart                 | LLL          | 1       |
| cart                 | KKK          | 1       |
+----------------------+--------------+---------+

с лимитом 2:

+----------------------+--------------+---------+
| page_name            | query_input  | count(*)|
+----------------------+--------------+---------+
| search               | CCC          | 10      |
| search               | EEE          | 8       |
| detail               | DDD          | 12      |
| detail               | FFF          | 11      |
| cart                 | III          | 6       |
| cart                 | JJJ          | 4       |
+----------------------+--------------+---------+

Обновление

У меня такое ощущение, что это неразрешимо, потому что я понял, что я на самом деле пытаюсь "выбрать из таблицы на ее порядок", а в MySQL порядок не учитывается при выборе ... Я прав

1 Ответ

0 голосов
/ 01 мая 2019

Попробуйте оператор in:

SELECT page_name, query_input, count(*) 
FROM table_name 
WHERE acct='XXXXX' 
  AND page_name IN ('search', 'detail', 'cart') 
GROUP BY query_input 
ORDER BY COUNT(*) DESC 
LIMIT 100
...