`facility` UInt16,
`timestamp` DateTime,
`hostname` String,
`tag` String,
`message` String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, hostname)
TTL timestamp + toIntervalDay(45)
SETTINGS index_granularity = 8192Записей много!
Можно как-то оптимизировать
SELECT DISTINCT hostname FROM syslogбез предварительного аггрегирования?
Почему order by такой? Если hostname не слишком много, стоит поменять их местами. Не знаю, оптимизирован ли distinct сейчас, group by host_name,... сильно ускорится
hostname LowCardinality(String) и делать select hostname from FROM syslog group by hostname или тупо вынести в отдельную таблицу, и сделать типа словаря
1) hostname замените тип на LowCardinality(string) 2) ORDER BY поменяйте поставьте сначала hostname а потом timestamp 3) SELECT DISTINCT hostname FROM syslog WHERE timestamp BETWEEN no() - INTERVAL 20 DAYS AND now() - такое допустимо?
1. да! Ускорение ~10 раз, если запрос поменять на "select hostname from syslog group by hostname" 2. да, еще быстрее, но "поломался" поиск без участия hostname, ОЧЕНЬ медленно. Пришлось вернуть "ORDER BY (timestamp, hostname)" обратно.
какой конкретно поиск? where что? как у вас таблица партиционирована?
CREATE TABLE default.syslog ( `severity` UInt16, `facility` UInt16, `timestamp` DateTime, `hostname` LowCardinality(String), `tag` String, `message` String ) ENGINE = MergeTree() PARTITION BY toYYYYMM(timestamp) ORDER BY (timestamp, hostname) TTL timestamp + toIntervalDay(45) SETTINGS index_granularity = 8192 Если ORDER BY поменять местами, то SELECT formatDateTime(timestamp, '%m/%d %H:%M'), hostname, severity, tag, message FROM syslog WHERE timestamp >= $value1 AND timestamp < $value2 AND message like $msg ORDER BY timestamp ASCвозвращается ОЧЕНЬ медленно. Понятно, что если добавить "AND hostname = ..." запрос возвращается быстро
сделайте ORDER BY (toStartOfHour(timestamp), hostname)
спасибо, попробую.
Сделал, но разница несущественна даже с toStartOfDay. Заметил другую проблему: переходы на "далекую" страницу до минуты и более SELECT * FROM syslog WHERE timestamp >= toDate('2020-11-02') AND timestamp < NOW() AND hostname='myhost' LIMIT 1000 OFFSET 1053000
OFFSET 1053000 -- а чего вы ожидали собственно? Чуда? Нет. Деда мороза не бывает.
я посоветовал такой ORDER BY (toStartOfHour(timestamp), hostname) чтобы работали по индексу запросы вида where hostname = ? and timestamp between
А разве не наоборот должны быть поля в ордер бай для вашего примера?
есть хитрость в КХ, он умеет делать skip scan, для лидирующих полей в индексе, что-то вроде oracle-fast-full-index-scan, если кардинальность лидирующего поля мала Valeriy наоборот отказывался делать, у хоста кардинальность большая, а ему нужно делать запросы с фильтрацией по дате, без фильтра по хосту
Обсуждают сегодня