@clickhouse_ru

Страница 51 из 723
Alexey
20.01.2017
18:00:28
@milovidov_an кто может пояснить как делается join 3х таблиц на уровне данных? т.е. не ясен момент: в документации говорится что будет полная выборка правой таблицы и левая будет заджойнена стримом. если делаешь второй джойн, то значит все предыдущие данные должны умещаться в память?
JOIN трёх таблиц сейчас можно написать только с помощью подзапросов, сведя его к JOIN двух таблиц. Данные "правого" подзапроса должны помещаться в память. Если в правом подзапросе будет ещё один JOIN - значит весь его результат тоже должен помещаться в память.

еще как быстрое улучшение прогресса, можно добавить memory_usage в вывод?
Хотим добавить. Там правда две величины - сумма по серверам и максимум по серверам. Максимум интересует, потому что именно на него накладываются ограничения. И ещё, прогресс-бар в клиенте станет двухстрочным. Мелочь, но чуть-чуть беспокоит.

А неплохо было бы перевести click house на блокчейн
Не знаю, но можно использовать ClickHouse для аналитики blockchain. Пример: https://blockchair.com/ - работает на ClickHouse.

Artem
20.01.2017
18:04:14
О мы как раз хотим его использовать тоже в блокчейне

Google
Alexey
20.01.2017
18:06:56
https://twitter.com/blockchair https://vk.com/blockchair

Artem
20.01.2017
18:10:34
Спасибо

prll
20.01.2017
18:23:19
до сих пор выдает: Code: 86. DB::Exception: Received from 127.0.0.1:9000. DB::Exception: Received error from remote server http://local-host/publisher_sites.php. HTTP status code: 500, body: .
Разницы в таймаутах между словарями нет, а бага на залипание плохого кода ответа возможно есть, будет исследовано.

Nikita
20.01.2017
18:23:20
До меня тут донесли, что мой поисковик пиарят, я тут :) Буду немного рассказывать про это на ближайшей конференции http://www.osp.ru/iz/blockchain

Всем доброго вечера!

Блокчейн — сам по себе — децентрализованная БД + механизм прихождения к консенсусу по вопросу “какие записи внесены в каком порядке”, поэтому Кликхаус тут не очень подходит. Но для аналитики Кликхаус — просто бомба.

Igor
20.01.2017
19:19:19
Добрый вечер, хочу презентовать пользователям CHGui - построение графиков и узнать что вы думаете о таком подходе к настройке графики - настройки прямо в запросе пишутся , и может кто то сталкивался с похожим решением в открытых/коммерческих продуктах -> чтобы можно было не изобретать, а просто откопировать документацию/решения )) Для простых графиков все просто, а вот для Sankey/Treemap/Heatmap/punchCard - “велосипедостроение какоето” )) Скринкаст dev версии: https://monosnap.com/file/O0tlFI6MJj5opkaOXjtJ5bYgjUjCyT

Alexey
20.01.2017
19:20:51
пытается ли scheduler вычислить сколько потребуется памяти для запроса?
По-умолчанию не пытается. Есть отдельные настройки - max_memory_usage_for_user и max_memory_usage_for_all_queries. Они работают весьма просто. Так, если max_memory_usage_for_user = 10 GB, и уже есть запросы, которые заняли 9.9GB, то следующий запрос будет почти сразу кидать исключение о том, что max_memory_usage_for_all_queries превышено.

Nikita
20.01.2017
19:23:36
Алексей, пользуясь случаем, всё хотел спросить — не появился пока changelog?

Google
Alexey
20.01.2017
19:23:59
Наверное, я просто плохо знаю Docker.

Как лучше поступить, если нужно ходить в кликхаус, расположенный на отдельной машине? открыть порт http интерфейса наружу или хайли рекоммендед закрыться nginx-ом?
Делать, чтобы ClickHouse смотрел в интернет - не очень хорошая идея, даже не смотря на наличие пользователей с паролями, всяких ограничений и т. п. Если не в интернет, а в ограниченную сеть, то более-менее Ок.

я сейчас получаю "Memory limit (for query) exceeded: would use 9.34 GiB", знаю что могу увеличить. но надо же сначало понять
max_memory_usage. Увеличить на постоянно - см. users.xml users.xml обновляется без перезагрузки сервера.

Nikita
20.01.2017
19:32:02
Без changelog страшновато обновляться, потому что часть логики иногда висит на немного костылях :)

rows_before_limit_at_least вроде бы точно работает с FINAL

Igor
20.01.2017
19:50:13
> @milovidov_an >Вроде бы в EventQL. Как раз с него и взял идею писать прямо в запросе >То, что на видео - уже хочу использовать. Это готово? Пока нет, думаю/планирую собрать за 2-3 недели до стабильного состояния и выкатить одним большим обновлением - постарвюсь успеть к след. митапу )) Сейчас просто оочень не стабильно - только сегодня прикрутил Sankeys

Nikita
20.01.2017
19:54:10
@garikanet мм. а я правильно понимаю, что я могу взять nginx, поднять https, поднять basic авторизацию, засервить clickhouse-frontend, в nginx прпоисать location который будет проксировать в http api clickhouse, прописать этот путь в clickhouse-frontend и оно как-то заработает и можно давать ребятам уже играться с запросами? правда немного пугает, что нужен не RO пользователь.

Igor
20.01.2017
20:04:32
Да, если перед CH поставить nginx -> в GUI указать http://ip то будет работать ... мы у себя прямо со сборки guiclickhouse.smi2.ru подключаемся к CH, но у нас iptables+vpn фичу RO юзера - поправлю в следующем релизе , проблема в том что gui послывает всегда параметр max_rows - который под ro вызывает ошибку переопределения в ch Да и мне как то писать drop / create table в gui приятнее )

Kirill
21.01.2017
11:03:46
Привет, может кто-нибудь подсказать по структуре массивов в нативном протоколе, например у меня есть таблица CREATE TABLE example ( IntArray Array(Int8), StrArray Array(String) ) ENGINE = Memory мне приходит пакет вида: column name - string (uvariant (strlen) + []byte (str)) column type - string (uvariant (strlen) + []byte (str)) { // data { array len (uvariant) } values } мне интересны первые 8 байт, сначала в них идет длина, но она переменной длины, после 8 байт идут данные массива которыя я вычитываю в зависимости от типа интересует как получить данный офсет и зачем он нужен?

f1yegor
21.01.2017
12:15:18
JOIN трёх таблиц сейчас можно написать только с помощью подзапросов, сведя его к JOIN двух таблиц. Данные "правого" подзапроса должны помещаться в память. Если в правом подзапросе будет ещё один JOIN - значит весь его результат тоже должен помещаться в память.
т.е. если я не путаю, то должно быть написано так(subselect on left, вместо subselect on right, или они семантически получатся одинаковыми?)# subselect on left select <> FROM table1 ALL INNER JOIN (select <> FROM ( select <> FROM table2 ALL JOIN table3 USING (key1) )) USING (key2) # subselect on right select <> FROM (select <> FROM ( select <> FROM table1 ALL JOIN table2 USING (key1) ) ALL INNER JOIN table3 ) USING (key2)

Darafei
21.01.2017
15:33:14
эээм, комментарии через решётку?

Roman
21.01.2017
18:32:06
на это похоже http://airbnb.io/superset/
Нее, суперсет это классический BI, а у Igor Str ноутбук вроде цепеллина получается. Еще не получился, конечно. Но в эту степь копает. Ноутбук с основным языком Clickhouse SQL и расширениями для визуализации.

Igor
21.01.2017
19:00:38
Да мне ноутбук ближе по стилю оказался. Но идеи из суперсета я тоже планирую реализовать, пользовался им год назад на протяжении полугода - крутой тулл но сыроват был ) Я решил делать типа : eventql + periscopedata для CH и для mySQL/pgSQL с упором на написание запросов руками без возможности drag&drop (bi). Уже в dev ветки такие вещи, как схлопывать запросы, автоформат, подсказки по каждой ф-ции ch, автодополнения словорей / ф-ции + хоткеи для удобной навигации ну и графики.

Google
f1yegor
21.01.2017
19:01:44
это еще на опубликовано?

Igor
21.01.2017
19:05:04
можно собрать ветку devigor1701 - но она очень не стабильна ...

f1yegor
21.01.2017
19:05:33
github?

Igor
21.01.2017
19:06:06
да

changelog https://github.com/smi2/clickhouse-frontend/blob/devigor1701/README.md#changelog

f1yegor
21.01.2017
19:07:21
а, понял. это я уже задеплоил и немного посмотрел

Alexey
21.01.2017
20:25:48
Привет, может кто-нибудь подсказать по структуре массивов в нативном протоколе, например у меня есть таблица CREATE TABLE example ( IntArray Array(Int8), StrArray Array(String) ) ENGINE = Memory мне приходит пакет вида: column name - string (uvariant (strlen) + []byte (str)) column type - string (uvariant (strlen) + []byte (str)) { // data { array len (uvariant) } values } мне интересны первые 8 байт, сначала в них идет длина, но она переменной длины, после 8 байт идут данные массива которыя я вычитываю в зависимости от типа интересует как получить данный офсет и зачем он нужен?
Для массива будут идти подряд два куска с данными. Сначала - смещения массивов - это числа UInt64 и их столько, сколько строк в блоке. Смещение в позиции i - это суммарное количество элементов во всех массивах до i-го, включительно. Другими словами, это - смещение (в количестве элементов) до начала i+1-го массива. Последнее смещение - это суммарное количество элементов всех массивов. Следующий кусок данных - это все элементы массивов, уложенные подряд. Пример: массивы [1], [10, 11] смещения будут записаны так: 1, 3 элементы будут записаны так: 1, 10, 11

И ещё: > uvariant (strlen) Правильно было бы написать - uvarint. Это очень частая ошибка. Почти всегда varint при взгляде читьается как variant.

f1yegor
21.01.2017
21:12:03
а отличие не в том, что в 'subselect on left' у меня выбираются данные из таблицы 3 в память, далее стрим join c таблицей 2, и результат стрим join с таблицей один. а во втором случае идет выборка всего в память из таблицы 3, потом выборка в память из т2, потом стриминг join т1 с т2, а потом ???

пытаюсь осознать "At the beginning of query execution, the subquery specified after JOIN is run, and its result is saved in memory. Then it is read from the "left" table specified in the FROM clause, and while it is being read, for each of the read rows from the "left" table, rows are selected from the subquery results table (the "right" table) that meet the condition for matching the values of the columns specified in USING."

Alexey
21.01.2017
21:36:18
1. - из table3 составляется хэш-таблица в оперативке; - читаем из table2 и делаем JOIN с table3; - из результата составляется хэш-таблица в оперативке; - читаем из table1 и делаем JOIN с этим. 2. - из table3 составляется хэш-таблица в оперативке; - из table2 составляется хэш-таблица в оперативке; - читаем из table1 и делаем JOIN с table2 и в том же проходе делаем JOIN с table3.

f1yegor
21.01.2017
21:39:42
т.е. потенциально вариант 1 есть меньше оперативы, но вариант 2 может получаться быстрее

Alexey
21.01.2017
21:41:02
Зависит от соотношения размеров таблиц и то, насколько меньше результат после JOIN. PS. Если у тебя в запросах есть ещё всякие WHERE, то лучше засовывать их в подзапрос (так как сейчас WHERE при выполнении делается после JOIN).

f1yegor
21.01.2017
21:42:46
да, у меня все WHERE внутри.

спасибо за объяснения

Боб
22.01.2017
18:59:10
А для CollapsingMergeTree у вас данные где-то во внешнем хранилище копятся? (Чтобы вставлять строку со знаком минус и предыдущими значениями)

И можно ли CollapsingMergeTree или SummingMergeTree научить схлопывать строки применением своей функции между двумя строками?

Google
Боб
22.01.2017
20:12:11
Или еще лучше: агрегировать в два уровня и при этом не требовать много памяти. Например нужно построить отчет: сколько пользователей сделали больше 2 кликов и обобщить данные по странам. Хотелось бы чтобы кликхаус агрегировал данные по пользователю или нескольким пользователям, затем применял бы изменения к конечной агрегации по странам и обработанных пользователей забывал переходя к новым. Если сделать что то вроде: select country, sumIf(click >2) from (select any(country) as country, count() as click from log group by userId) То сервер сначала целиком посчитает весь внутренний запрос и только потом внешний. Ручная оптимизация выглядит как запрашивание агрегаций по пользователям небольшими кусками: по интервалам userid и потом конечные расчеты во внешней системе. Это позволяет экономить много оперативки. Можно ли подобную оптимизацию сделать внутри запросов?

f1yegor
22.01.2017
20:19:23
а почему не сделать просто select country, count(*) from log where click >2 group by country

f1yegor
22.01.2017
20:26:40
select country, uniqIf(userId, click > 2) from log group by country

papa
22.01.2017
22:31:49
если я правильно понимаю задачу, то схема данных имеет вид table log( userid, country ... )по которой надо посчитать кол-во людей, у которых было больше двух кликов, что и делает запрос select country, sumIf(click > 2) from ( select any(country) as country, count() as click from log group by userId)который в общем случае не работает, т.к. userid имеет большую кардинальность. из того как объявлен click можно предположить, что каждая строка лога - это отдельный клик. также, видимо, предполагается что страна пользователя меняется редко. запрос select country, uniqIf(userId, click > 2) from log group by countryсработал бы в случае, если строка лога была бы пользователем, и в ней была колонка с количеством кликов. для этого, возможно, подойдет AggregatingMergeTree, countState(), вот это все. еще наверное в ключ надо добавить дату, т.к. без окна по времени любой запрос к log со временем работать перестанет.

f1yegor
22.01.2017
22:34:30
А, понятно

Боб
23.01.2017
07:49:06
Про даты это понятно, тут я их специально опустил для упрощения восприятия. Log это таблица, в которую вставлен лог апача, пока что без предварительной обработки. А статистика в основном нужна по уникам. При этом в разных разрезах: страны, устройства (телефон, десктоп), источники трафика и т.п. за произвольные интервалы времени. А есть ли какой-то способ чтобы кликхаус сам агрегировал информацию из таблицы логов в таблицу пользователей. Чтобы выборку потом уже из пользователей делать?

В идеале что-то вроде SummingMergeTree, только чтобы суммирование происходило собственной функцией. Т.е. например есть две записи о пользователе - я хочу оставить одну, но не просто сложить числа, а например запомнить время последних 10 кликов и соответственно при каждом слиянии эти "последние 10" должны сливаться и укорачиваться по длине до 10 элементов. А не просто складываться или работать как map.

Alexey
23.01.2017
07:51:51
Я бы писал просто: SELECT Country, uniq(UserID) FROM log GROUP BY Country ORDER BY uniq(UserID) DESC Пямяти такой запрос потребляет мало. Разница с предложенным вами запросом лишь в случае, когда пользователь был в нескольких странах, и нужно учесть его только в одной.

Боб
23.01.2017
07:53:51
Разница еще в том, что в вашем запросе считается количество уников, а в моём количество уников, которые кликнули минимум два раза.

Alexey
23.01.2017
07:54:17
А. Совсем другое дело. Не обратил внимания.

Функциональности сброса временных данных агрегации в случае, когда данные одного ключа идут при обработке подряд - нет.

Боб
23.01.2017
07:55:48
на самом деле нужно считать и другие агрегации в разрезе пользователя, например уходил ли пользователь с сайта (т.е. тут нужно как-то времена кликов соотносить. Сейчас пробую добавить колонку "время предыдущего клика" и потом придумать как её при записи в лог добавлять), паузы между кликами - т.е. количество кликов когда время между кликами больше n секунд (пользователь ушел, потом на след. день вернулся) и т.п.

Alexey
23.01.2017
07:56:55
А для CollapsingMergeTree у вас данные где-то во внешнем хранилище копятся? (Чтобы вставлять строку со знаком минус и предыдущими значениями)
Да, для этого у нас используется отдельная структура данных, никак не связанная с ClickHouse.

Боб
23.01.2017
09:34:17
А есть способ "Сдвинуть" элементы массива на 1 вперед и потом в конец добавить еще один элемент (пустой). Задача: собираю таблицу по пользователям. Для каждого пользователя получаю массив времён, когда он заходил - groupArray(Timestamp) as Times. Дальше мне нужно будет сравнить разницу между соседними Timestamp чтобы понять например - были ли у пользователя возвраты. Я себе это вижу примерно так SELECT arrayExists( (Time1,Time2) -> Time2 != 0 AND Time1 - Time2 > 86400, Times, append(shift(Times, 1), 0) ) as isReturned Интересует как сделать часть: append(shift(Times, 1), 0) ) т.е. откусить от массива первый элемент и добавить в конец пустой элемент. Или так: SELECT arrayExists( (Time1,Time2) -> Time1 - Time2 > 86400, Times[:length(Times)-1], Times[1:] ) as isReturned т.е. передать в arrayExists два массива, у одного откушен первый элемент. У другого - последний.

Vladislav
23.01.2017
10:29:57
странное поведение, если указать в условии несуществующие даты: SELECT DISTINCT download_date FROM analytics.apps_store_downloads WHERE (download_date >= '2016-11-28') AND (download_date <= '2016-11-31') ORDER BY download_date ASC ┌─download_date─┐ │ 2016-11-28 │ │ 2016-11-29 │ │ 2016-11-30 │ │ 2016-12-01 │ └───────────────┘ SELECT DISTINCT download_date FROM analytics.apps_store_downloads WHERE (download_date >= '2016-11-28') AND (download_date <= '2016-11-32') ORDER BY download_date ASC Ok.

почему в первом случае что-то возвращается, а во втором – нет?

Igor
23.01.2017
10:32:14
:) select toDate('2016-11-30'), toDate('2016-11-31'), toDate('2016-11-32') FORMAT Vertical; Row 1: ────── toDate(\'2016-11-30\'): 2016-11-30 toDate(\'2016-11-31\'): 2016-12-01 toDate(\'2016-11-32\'): 0000-00-00

видимо, поэтому

Google
Igor
23.01.2017
10:32:43
насчет 2016-11-31 - поржал :))

о, с февралем так же прокатывает, 31 февраля == 2 марта

Eduard
23.01.2017
10:47:28
?

Shine
23.01.2017
11:01:26
Ребят, подскажите, у меня есть поля с массивы строк, хочется, что бы мы фильтровали по этим полям с логикой И (как в постгресе есть @> - contains), т е чтобы мы условие возвращало истину ,только если все искомые элементы есть в массиве Когда делаем так select query_id, tags, arrayAll(x -> has(['3rd generation', '5th generation'], x), tags) as has_tags from queries_1 limit 10; мы ограничены количеством элементов массива tags. Если количество элементов массива tags меньше, чем количество запрашиваемых элементов, то мы получим те строки массива tags, которые содержат хотя бы один элемент. А нам нужно обязательно, чтобы в результате выдавались только те строки, которые имееют все запрашиваемые теги (тут мы не фильтруем, а для теста выводим булеву колонку, но не суть)

Nikita
23.01.2017
11:02:25
а в jdbc и readonly пользователь не дружат? ругается на "Cannot override setting (extremes) in readonly mode"

дурья моя башка, readonly же может быть 2

Боб
23.01.2017
11:20:35
а еще лучше: arrayCount( arrayFilter( x-> has(['a', 'b', 'c']) ) ) == 3

arrayCount( arrayFilter( x-> has(['a', 'b', 'c']),tags ) ) == 3

Боб
23.01.2017
11:28:37
Интересно а как в метрике считают данные по пользователям - у вас же тоже на входе просто логи, а на выходе есть какая-то статистика по посетителям? Если я правильно понял предыдущие диалоги, то посетители у вас лежат в таблице CollapsingMergeTree. Где-то снаружи вы отдельно определяете что клик принадлежит такому-то посетителю, снаружи обновляете его счетчики (время последнего клика, количество кликов и т.п.), и скидываете лог изменений в CollapsingMergeTree. Затем, когда надо выдать статистику по пользователям делаете уже запрос к таблице посетителей и её доагрегируете с учетом строк или FINAL? И сколько памяти кушает FINAL - так же как загрузить всю таблицу в память и посчитать по GROUP BY или меньше?

Страница 51 из 723