
Константин
24.01.2017
19:54:44
Да, спасибо. Помогло.
Еще нашел багу, при использовании $columns не получается использовать словари

Roman
24.01.2017
19:57:57

Abdulla
25.01.2017
07:50:32
кто-нибудь в курсе, существует ли в природе генератор sql-запросов для clickhouse под nodejs? на подобии squel: https://hiddentao.com/squel/

Google

Andrew
25.01.2017
09:27:32
и чем не подходит squel?

f1yegor
25.01.2017
09:45:56
sum(max(order_value)) Aggregate function max(order_value) is found inside another aggregate function in query.
почему существует такое ограничение https://github.com/yandex/ClickHouse/blob/8c0e81f8cb0960e4cffdacea10ad27f049fe0302/dbms/src/Interpreters/ExpressionAnalyzer.cpp#L2065 ?
и получается что обойти его можно пока только завернув это в отдельный select

Maxim
25.01.2017
09:50:01
Это вроде не часть ANSI SQL. Oracle поддержку таких вложенных аггрегирующих запросов считает конкурентным преимуществом

Igor
25.01.2017
09:50:25
угу, в постгре вроде тоже не поддерживается

f1yegor
25.01.2017
09:50:48
посчитать sum(max(<>)) разве нельзя в обычных db?

Darafei
25.01.2017
09:51:59
можно, но с расписыванием в подзапросы

Ilyas
25.01.2017
09:55:45

Abdulla
25.01.2017
11:31:23
А зачем?
чтобы не заниматься форматированием текста вручную, т.к. задача — дать пользователям гибкий конструктор отчётов
и чем не подходит squel?
да вроде подходит, если переопределять методы форматирования под clickhouse, думал может что получше посоветуют

Боб
25.01.2017
12:10:41
Делаю запрос:
SELECT OrderID, sum(debits) as debits FROM (
SELECT
...
FROM
(
....
) ANY LEFT JOIN
prod.PriceSources
USING Country,Source
) GROUP BY OrderID
WITH TOTALS FORMAT JSON
Почему-то получаю ошибку:
Code: 60, e.displayText() = DB::Exception: Table default.prod.PriceSources doesn't exist., e.what() = DB::Exception
Если заменить имя таблицы на подзапрос
) ANY LEFT JOIN
(select * from prod.PriceSources)
USING Country,Source
то запрос выполняется нормально

Google

papa
25.01.2017
13:02:56


Yury
25.01.2017
13:14:31
Привет!
Подскажите как лучше обработать ситуацию. Как я понял в CH в Int поля null вставить нельзя. Вообще такой привычной вещи в БД как null c CH нет.
У меня в таблице поле idnumber, определил как
idnumber Int64 DEFAULT -1,
В CSV приходит null:
,,На загрузке падает:
Column 20, name: idnumber, type: Int64, ERROR: text ",,,0<LINE FEED>17438" is not like Int64

Боб
25.01.2017
13:14:50
джойн работает только для подзапросов
не, имя таблицы тоже можно указывать:
https://clickhouse.yandex/reference_ru.html#Секция%20JOIN
Вместо подзапроса может быть указано имя таблицы. Это эквивалентно подзапросу SELECT * FROM table,
т.е. по идее оба варианта должны дать один и тот же результат, просто имя таблицы писать короче
тут похоже на баг, что к имени таблицы прибавляется имя базы данных по умолчанию, хотя имя базы я уже указал.

Igor
25.01.2017
13:17:07
Привет!
Подскажите как лучше обработать ситуацию. Как я понял в CH в Int поля null вставить нельзя. Вообще такой привычной вещи в БД как null c CH нет.
У меня в таблице поле idnumber, определил как
idnumber Int64 DEFAULT -1,
В CSV приходит null:
,,На загрузке падает:
Column 20, name: idnumber, type: Int64, ERROR: text ",,,0<LINE FEED>17438" is not like Int64
как NULL приходит в CSV, прям "NULL"? насколько я помню, в CSV, TSV и прочих используется \N

Yury
25.01.2017
13:18:45
Как подряд два разделителя

Igor
25.01.2017
13:20:30
т.е. просто пустой столбец?
тогда должен привестись к DEFAULT значению, вроде

Yury
25.01.2017
13:20:44
Как-то так
aaaa,bbb,1,,111
Да, просто пустой столбец

Igor
25.01.2017
13:21:30
а порядок столбцов точно совпадает?

Yury
25.01.2017
13:22:59
да, совпадает
Попробую coalesce на источнике сделать

Igor
25.01.2017
13:27:49
ваще странно, должно вставляться
:) CREATE TABLE test2 (date Date, idnumber Int64 DEFAULT -1, data String) ENGINE = MergeTree(date, (date), 8192);
~ ❯ echo -ne '2017-01-25,,some_data' | curl "http://127.0.0.1:8123/?query=INSERT+INTO+test2+FORMAT+CSV" -i --data-binary @-
HTTP/1.1 200 OK
~ ❯ echo -ne '2017-01-25,more_data' | curl "http://127.0.0.1:8123/?query=INSERT+INTO+test2+(date,+data)+FORMAT+CSV" -i --data-binary @-
HTTP/1.1 200 OK
:) SELECT * FROM test2 FORMAT CSV;
"2017-01-25",-1,"more_data"
"2017-01-25",0,"some_data"

Yury
25.01.2017
13:39:34
Поэкспериментирую ещё
Спасибо большое

Константин
25.01.2017
13:52:51
Привет!
Подскажите как лучше обработать ситуацию. Как я понял в CH в Int поля null вставить нельзя. Вообще такой привычной вещи в БД как null c CH нет.
У меня в таблице поле idnumber, определил как
idnumber Int64 DEFAULT -1,
В CSV приходит null:
,,На загрузке падает:
Column 20, name: idnumber, type: Int64, ERROR: text ",,,0<LINE FEED>17438" is not like Int64
Сталкивался с такой проблемой, CH не воспринимает как null, если идет двойной разделитель, я принудительно экранировал все поля в csv. Даже пустые
В частности, используется такой конфиг для апдейта словарей из постгреса: with (format csv, header, force_quote(name,ad_pos,ad_source), null "''")

Yury
25.01.2017
14:02:13
Спасибо

Google

Yury
25.01.2017
14:07:17
Ещё хотел спросить.
Есть MATERIALIZED представления. Вообще рекомендуется их использование? Если например SQL запрос под представлением содержит join (или join-ы) ?
Или же лучше синхронизировать действие внешних вставок данных и последующего расчета представления для анализа через внешний планировщик?

Alexander
25.01.2017
14:12:06
materialized view технически такая же таблица
с точки зрения запросов ничем не отличается

Yury
25.01.2017
14:13:45
С точки зрения запросов - да

Константин
25.01.2017
14:14:20
У меня используются, очень удобно. Особенно если движек еще SummingMergeTree
для аггрегации данных :)

Yury
25.01.2017
14:16:19
а если join под матвью? Не получится неконсистентных данных

?Zloool?
25.01.2017
14:17:14
О, разраб питон библиотеки после трёх месяцев без комитов проснулся
https://github.com/Infinidat/infi.clickhouse_orm

Alexander
25.01.2017
14:18:59
Да, мы тоже используем для агрегации. Получается некоторый аналог транзакционности -- данные попадают во все связанные MV, или никуда

Igor
25.01.2017
14:19:23
https://github.com/cloudflare/sqlalchemy-clickhouse

Yury
25.01.2017
14:25:17
Например, при наличии GROUP BY, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы.
Правильно я понимаю что без SummingMergeTree матвью использовать не рекомендуется?

Боб
25.01.2017
15:06:45
А union как-то следит за используемыми ресурсами или исполяет все параллельно и валится если на все сразу памяти не хватит?
В доке написано что может выполняться параллельно. А может ли он не выполняться параллельно если памяти на все куски сразу не хватит?

Dmitry
25.01.2017
15:59:35

Igor
25.01.2017
16:05:27
чуть-чуть живо, я с superset пытался попользоваться
не знаю, кто из них косячил в итоге, но на сколько-нибудь сложных запросах валился

Dmitriy Ch
25.01.2017
16:51:02
А есть какие то ручки, которые можно покрутить, чтобы ускорить репликацию?) Подключили третий сервер в кластер, таблички занимают примерно 12ТБ, второй день уже копируется и все никак. цпу, диск и сеть загружены по минимуму.

Google

Dmitry
25.01.2017
16:53:13
Я какая скорость передачи? Что dstat говорит?
У нас всегда КХ всю сеть выедал, даже шейпить приходилось

Dmitriy Ch
25.01.2017
16:57:09
дстат говорит, что я соврал( не в тот график смотрел и правда вся сеть занята
спасибо

Alexey
25.01.2017
19:04:29
Сталкивался с такой проблемой, CH не воспринимает как null, если идет двойной разделитель, я принудительно экранировал все поля в csv. Даже пустые
В CSV в качестве NULL, так же, как в TSV, используется \N.
Думал над другими вариантами. Например, для пустоты возникает неоднозначность с пустой строкой, а для NULL - со строкой, содержащей NULL.
Можно сделать, чтобы для Nullable типов эта неоднозначность разрешалась в сторону NULL, а если людям нужна пустая строка или строка с буквами NULL, то требовать писать её в кавычках.


Peter
25.01.2017
22:13:53
Привет, подскажите, а правильно ли использовать движок ReplicatedReplacingMergeTree, чтобы иметь возможность делать аналог UPDATE?
Например мы храним данные о визитах (site_id, visitor_id, user_id, date, ...), и для каждого нового посетителя генерируется уникальный visitor_id под которым мы сохраняем все его действия на сайте, и когда он прошел авторизацию мы хотим "склеить" эти данные, тоесть во всех данных о его визитах заполнить колонку user_id. Или лучше сделать отдельную таблицу (visitor_id, user_id, ...) и делать join когда нужно построить отчет?

Dmitry
25.01.2017
22:17:11
Так будет работать, но надо понимать, что ReplacingMergeTree схлопывает данные в фоне
имхо это создаст больше неудобств
Я бы сделал словарь visitor_id -> user, это будет куда удобнее и быстрее чем join
Да и в словаре можно хранить больше чём просто один id

Peter
25.01.2017
22:27:41
Спасибо. Тогда можно подключить сразу mongo как внешний словарь, у нас там информация о visitor/user

Alexey
25.01.2017
22:35:03
Но только если посетителей не слишком много. Иначе словарь будет трудно уместить в оперативке, придётся делать cache словарь, а он будет требовать запросов в источник...

Peter
25.01.2017
22:51:41
А что лучше/быстрее cache словарь или отдельная таблица и join ? Если выборки для фильтров иногда нужно делать по полям из этой таблицы (и также данные в ней, поля user например могут часто меняться)

Alexey
25.01.2017
23:09:55
Отдельную таблицу для JOIN ведь тоже будет трудно обновлять.
Возможность нормально делать JOIN зависит от того, какой объём данных будет читаться и подниматься в память из "правой" таблицы. Если в рамках одного запроса из правой таблицы читается какой-то не слишком большой диапазон данных, то всё Ок.

Peter
25.01.2017
23:18:43
Спасибо большое.

Константин
26.01.2017
06:41:34
Доброе утро! У меня есть таблица, в которой дата и время хранятся раздельно (так исторически сложилось). Сейчас надо как-то объединить это (для расчетов), но не получается:
select toDateTime(concat(toString(date),' ',toString(hour),':00:00'))....
Выдает ошибку: Cannot parse datetime 2017-01-26 6:00:00: Cannot parse DateTime from String

papa
26.01.2017
06:43:17
hour*3600 подойдет?

Константин
26.01.2017
06:47:23
спасибо за идею ?

Google

Константин
26.01.2017
06:47:49
как-то так получилось: toUInt32(toDateTime(date))+toUInt32(hour*3600)

Боб
26.01.2017
06:52:48

Константин
26.01.2017
06:53:34
да, так оно и было... уже сам догадался и проверил

Боб
26.01.2017
09:42:45
@milovidov_an
Алексей, подскажите пожалуйста про UNION ALL
В документации написано что
Запросы - части UNION ALL могут выполняться параллельно, и их результаты могут возвращаться вперемешку.
Это означает что они могут выполняться параллельно, а могут и нет в зависимости от ресурсов?
Конкретно интересует могут ли UNION ALL понять что ресурсов на всех не хватит и выполняться последовательно или параллельно например по 2 штуки, а не 30 запросов сразу?
у меня в запросах есть GROUP BY по пользователям и за сутки данные в память влезают, а за неделю-месяц уже нет.
Посуточной агрегации мне хватит. Вот хочу сделать подзапрос и разбить период на сутки и потом результат объединить в UNION, чтобы потом доагрегировать.


Maxim
26.01.2017
10:38:53
Всем привет! Не запускается сервер CH. В логах ошибка:
2017.01.26 13:23:24.737 [ 5 ] <Error> statistic.Bets (StorageReplicatedMergeTree): checkPartAndAddToZooKeeper: node /clickhouse/tables/1/Bets/replicas/db105/parts/20170126_20170126_1206420_1206435_2 already exists
2017.01.26 13:23:24.752 [ 5 ] <Error> DB::StorageReplicatedMergeTree::queueTask(DB::BackgroundProcessingPool::Context&)::<lambda(DB::StorageReplicatedMergeTree::LogEntryPtr&)>: Code: 235, e.displayText() = DB::Exception: Part 20170126_20170126_1206420_1206435_2 already exists, e.what() = DB::Exception, Stack trace:
2017.01.26 13:10:30.088 [ 25 ] <Error> BaseDaemon: ########################################
2017.01.26 13:10:30.088 [ 25 ] <Error> BaseDaemon: (from thread 7) Received signal Segmentation fault (11).
2017.01.26 13:10:30.088 [ 25 ] <Error> BaseDaemon: Address: NULL pointer.
2017.01.26 13:10:30.094 [ 25 ] <Error> BaseDaemon: 1. clickhouse-server-02(tcmalloc::ThreadCache::ReleaseToCentralCache(tcmalloc::ThreadCache::FreeList*, unsigned long, int)+0xeb) [0x2bc6bcb]


Yury
26.01.2017
11:57:42
Тестирую использование движка CollapsingMergeTree для своих задач. Ощущение что ошибка.
Сценарий.
Создаю таблицу:
CREATE TABLE IF NOT EXISTS dwh_pilot.test_cmt
(
log_dt Date,
log_dttm DateTime,
record_id UInt64,
actual_flg Int8
) ENGINE = CollapsingMergeTree(log_dt, (record_id), 8192, actual_flg);Делаю вставку записи о том, что запись добавлена:
INSERT INTO dwh_pilot.test_cmt (log_dt, log_dttm, record_id, actual_flg)
VALUES ('2017-01-26', now(), 1, 1)Делаю вставку записи о том, что запись устарела/удалена:
INSERT INTO dwh_pilot.test_cmt (log_dt, log_dttm, record_id, actual_flg)
VALUES ('2017-01-26', now(), 1, -1)Делаю select:
SELECT *
FROM test_cmt
ORDER BY log_dttm DESC
┌─────log_dt─┬────────────log_dttm─┬─record_id─┬─actual_flg─┐
│ 2017-01-26 │ 2017-01-26 14:49:39 │ 1 │ -1 │
│ 2017-01-26 │ 2017-01-26 14:49:30 │ 1 │ 1 │
└────────────┴─────────────────────┴───────────┴────────────┘
2 rows in set. Elapsed: 0.005 sec.Результат корректный.
Делаю select final:
SELECT *
FROM test_cmt
FINAL
ORDER BY log_dttm DESC
Ok.
0 rows in set. Elapsed: 0.004 sec.Результат корректный.
Делаю optimize:
OPTIMIZE TABLE test_cmt
Ok.
0 rows in set. Elapsed: 0.005 sec.Делаю select:
SELECT *
FROM test_cmt
ORDER BY log_dttm DESC
┌─────log_dt─┬────────────log_dttm─┬─record_id─┬─actual_flg─┐
│ 2017-01-26 │ 2017-01-26 14:49:39 │ 1 │ -1 │
│ 2017-01-26 │ 2017-01-26 14:49:30 │ 1 │ 1 │
└────────────┴─────────────────────┴───────────┴────────────┘
2 rows in set. Elapsed: 0.051 sec.Результат корректный.
Делаю select final:
SELECT *
FROM test_cmt
FINAL
ORDER BY log_dttm DESC
┌─────log_dt─┬────────────log_dttm─┬─record_id─┬─actual_flg─┐
│ 2017-01-26 │ 2017-01-26 14:49:30 │ 1 │ 1 │
└────────────┴─────────────────────┴───────────┴────────────┘
1 rows in set. Elapsed: 0.005 sec.Результат странный.
Подскажите, пожалуйста, это ошибка или я что-то делаю неправильно?
А если сделать ещё раз вставку об удаление то:
INSERT INTO dwh_pilot.test_cmt (log_dt, log_dttm, record_id, actual_flg)
VALUES ('2017-01-26', now(), 1, -1)
То и до optimize и после select final показывается 0 rows
Такое ощущение что optimize меняет порядок блоков и в этом случае select final начинает возвращать на самом деле "удалённую" версию данных...


Dmitry
26.01.2017
12:17:52
Кто-нибудь знает как взять первые n элементов массива?

Igor
26.01.2017
12:18:42
если нет - можно через arrayfilter + arrayenumerate

Dmitry
26.01.2017
12:22:09

Roman
26.01.2017
12:58:08
Всем привет! Какая политика работы в Yandex с партициями годичной давности или больше, доступ к которым хоть и очень редко, но все-таки нужен? Переносите ли вы их на более дешевые диски ?

Виктор
26.01.2017
12:59:26
Привет, не переносим
Но это скорее неправильно

Roman
26.01.2017
13:00:27
спасибо