Более быстрый выбор при фильтрации со вторым или третьим отсортированным столбцом - PullRequest
0 голосов
/ 19 июня 2020

У нас есть таблица временных рядов со следующим определением

CREATE TABLE timeseries.mytable
(
    `ts` DateTime('UTC'),
    `src_ip` String,
    `dst_ip` String,
    `col_other` String
)
ENGINE = MergeTree()
PARTITION BY toDate(tr)
ORDER BY (dst_ip,ts,src_ip)
SETTINGS index_granularity = 8192

SELECT count(*) FROM timeseries.mytable;
# Elapsed 0.004 sec. Has 383M records


SELECT count(*) FROM timeseries.timeseries WHERE dst_ip = 'a.b.c.d';
# Elapsed: 0.085 sec.

SELECT count(*) FROM timeseries.timeseries WHERE src_ip = 'a.b.c.d';
# Elapsed: 53.031 sec

Как видно выше, фильтрация данных с использованием первого отсортированного столбца (dst_ip) выполняется очень быстро.

Как Могу ли я сделать выбор, используя третий отсортированный столбец (src_ip) быстрее?

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Некоторые примечания:

  • третий запрос ( WHERE src_ip = 'ab c .d' ) работает медленно из-за того, что index не используется , а CH использует полное сканирование. Нет хорошего способа сделать это быстрее, кроме как изменить дизайн первичного ключа или если этот запрос вычисляет только агрегаты, используйте дополнительную AggregatingMergeTree -таблицу

  • варианты использования, которые вы предоставили выглядит искусственно, потому что вычисление количества строк по всем набору данных не является ключевым вариантом использования данных таймсерий. Почему результат не ограничен dst_ip и ts ?

  • рассмотрите возможность использования ClickHouse AggregatingMergeTree Approach , когда необходимо вычислить агрегированные -values ​​(как count в вашем случае)

  • дизайн первичного ключа требует понимания того, как CH использует его при оптимизации запросов (см. Primary Keys and Indexes в запросах , Дополнительные секреты производительности запросов ClickHouse )

  • рекомендуется использовать monotoni c index

  • , чтобы выбрать лучший индекс, необходимо провести серию тестов, чтобы найти индекс, наиболее подходящий для конкретных случаев использования


Я бы предложил следующий первичные ключи:

/* [pretty suspicious suggestion] Remove date-column (it makes much slower the all date range queries with a range less than Daily). */
ORDER BY (dst_ip, src_ip)

/* Define the granularity of date. Instead of toStartOfHour can be used any interval less than 'Daily' (where Daily is defined by partition key) */
ORDER BY (dst_ip, toStartOfHour(ts), src_ip)

/* Move the date to the first position (it makes faster queries with date range without dst_ip and get monotonic-index related advantages). */
ORDER BY (toStartOfHour(ts), dst_ip, src_ip)

Для каждого первичного ключа необходимо выбрать более эффективный Степень детализации индекса -значение.

0 голосов
/ 19 июня 2020

Добро пожаловать в Stackoverflow.

Вы должны попробовать провести тестирование, сохраняя другой порядок в предложении ORDER BY в зависимости от количества значений ваших столбцов. В этом случае, возможно, попытаться привести src_ip перед ts в ORDER по классам.

В движке MergeTree строки сортируются на основе ключей ORDER BY в каждом разделе.

После этого вы можете определите окончательное расположение столбцов в предложении ORDER by в зависимости от того, как ваше приложение будет запрашивать данные по большей части элементов.

Вы можете найти подобное обсуждение здесь .

...