Как оптимизировать Mysql Select с учетом на 3 ГБ таблицы - PullRequest
2 голосов
/ 12 марта 2019

У меня есть таблица с 37 000 000 строк и 3 ГБ данных.

CREATE TABLE `stats_raw` (
    `user_id` INT(11) NOT NULL,
    `date` DATETIME(6) NOT NULL,
    `ip` VARBINARY(16) NULL DEFAULT NULL,
    INDEX `stats_raw_user_id_index` (`user_id`),
    INDEX `stats_raw_date_index` (`date`),
    INDEX `stats_raw_user_id_data_index` (`user_id`, `date`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

Когда я пытаюсь выполнить следующий запрос (сгенерированный laravel, поэтому он может выглядеть странно):

select count(ip) as total, INET6_NTOA(ip) as ip
from `stats_raw`
where `user_id` = 1 and date(`date`) >= '2019-02-10'
group by `ip`
order by `total` desc
limit 10

Для возврата результатов требуется около 40 секунд.

Как я могу оптимизировать это на MySQL?

Ответы [ 2 ]

2 голосов
/ 12 марта 2019

Во-первых, я бы написал запрос как:

select count(ip) as total, INET6_NTOA(ip) as ip
from `stats_raw`
where `user_id` = 1 and `date` >= '2019-02-10'
group by `ip`
order by `total` desc
limit 10;

Во-вторых, вы хотите индекс на stats_raw(user_id, date, ip).

Тем не менее, не ясно, сколько данных обрабатывается. Я не думаю, что есть способ обойти сортировку для group by и order by, поэтому, если у вас много данных, вы не сможете ускорить этот запрос без дополнительных героических усилий (таких как ведение сводных таблиц). используя триггеры).

1 голос
/ 12 марта 2019

Гордон действительно прибил его с помощью запроса, поэтому мой ответ предполагает, что вы будете использовать его запрос.

Небольшое улучшение, которое вы можете попробовать, - изменить тип данных столбца date на DATE вместо DATETIME (при условии, что вам на самом деле не нужна часть времени.)

Таким образом вы можете уменьшить хранилище в этом столбце с 5 байтов (или 8, если используется версия MySQL старше 5.6) до 3 , что позволит загружать больше данных на один раз, и таким образом уменьшить некоторые накладные расходы.

Конечно, если вам нужна часть времени для других вещей, то это не вариант.

...