Высокопроизводительный запрос для подсчета многих данных - PullRequest
0 голосов
/ 25 февраля 2019

Таблица запросов:

requests
    +id (INT) AUTO_INCREMENT
    +title (VARCHAR)

Таблица статусов:

statuses
    +id (INT) AUTO_INCREMENT
    +title (VARCHAR)

Таблица отношений:

request_status (MANY TO MANY)
    +id (INT) AUTO_INCREMENT
    +request_id (INT) Foreign Key
    +status_id (INT)

Я хочу считать только те запросы, чей текущий status_id равен 2 .Текущий статус запроса (status_id) является последним в таблице request_status.

Каким будет идеальный высокопроизводительный запрос, если данные около 1600k

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019
SELECT COUNT(*) FROM request_status WHERE status_id = 2;

должно работать лучше всего, если я правильно понял ваш вопрос - что было бы для подсчета пар, в которых status_id равен 2.

0 голосов
/ 06 марта 2019

Схема для таблицы отношений имеет несколько недостатков.Я обсуждаю их здесь .

Но вместо этого давайте изменим схему, чтобы сделать ее еще более эффективной.Вместо 3 таблиц с отображением «многие: многие» имеется только одна таблица:

CREATE TABLE requests (
    id ...,
    latest_status  ENUM('eating', 'sleeping', 'running'),
    all_statuses    SET('eating', 'sleeping', 'running'),
) ENGINE=InnoDB;

(В качестве альтернативы вы можете использовать TINYINTs, но с другим синтаксисом.)

Когда статусдля заданных request изменений установите latest_status и "или" новый статус в all_statuses.

Чтобы проверить наличие последних running: WHERE latest_status = 'running'.

или, если используется какое-либо числовое значение: WHERE latest_status = 2.

0 голосов
/ 25 февраля 2019

Предполагая, что последний статус - это статус с наибольшим идентификатором:

SELECT COUNT(*)
FROM request_status
WHERE status_id = 2
AND NOT EXISTS (
    SELECT 1
    FROM request_status AS x
    WHERE request_id = request_status.request_id
    AND id > request_status.id
)

Или это:

SELECT COUNT(*)
FROM (
    SELECT 1
    FROM request_status
    GROUP BY request_id
    HAVING MAX(CASE WHEN status_id = 2 THEN id END) = MAX(id)
) AS x

Вам понадобятся некоторые индексы.Я предлагаю создать такие:

KEY ix1 (request_id, status_id)
KEY ix2 (status_id,  request_id)
...