
Alex
11.05.2018
12:03:47
Ну тогда какой смысл то?
В приведённом мной примере, взялось несколько кусков, которые в один тред мёржатся. есть мнение, что если один тред будет мёржить только 2 куска, то merge sort может быть повеселее и побыстрее

Wolf
11.05.2018
12:06:00
Ну а какая разница то, на вашем конфиге, все равно все идёт в фоне
Или у вас триллионы записей в час?

Alex
11.05.2018
12:11:09

Google

Wolf
11.05.2018
12:11:43
Ну на миллиардах вроде нет проблем таких
А что Ла выше 24 или диск ио больше гигабайта в секунду?

Alex
11.05.2018
12:13:02
Диск курит бамбук :)

Wolf
11.05.2018
12:13:57
Ну что то не то
А вставляете пачками по миллиону?

Alex
11.05.2018
12:14:12
Раз вы говорите что изменять ограничения на мёржи нет смысла, единственным вариантом, видимо, остаётся уменьшать размер пула бекграундных тредов?

Wolf
11.05.2018
12:14:46
Ну мелковато для миллиардов в час
Надо же две вставки в секунду примерно
Образно говоря

Alex
11.05.2018
12:15:33
На хост/шард/кластер?

Wolf
11.05.2018
12:15:48
Ну на реплику

Google

Wolf
11.05.2018
12:16:05
Да на все видимо

Alex
11.05.2018
12:16:27
При 100% INSERT загрузке на сервере вообще не видно использования CPU

Wolf
11.05.2018
12:16:27
Не пользуюсь сейчас дистрибьютед для вставки, про нее не могу сказать

Kirill
11.05.2018
12:22:18
SSD легко втыкают при интенсивной записи, в этом случае обычный диск и последовательная запись куда производительнее может быть

Michal
11.05.2018
12:25:45

Stas
11.05.2018
12:26:46
т.е сейчас я фактически все оборачиваю длинной конструкций if then else...

Michal
11.05.2018
12:27:11
Ну вот я и пробую у вас узнать зачем вам этот null :)
При использовании внутри агрегатной функции - он ничего не дает.
а вы используете его как раз внутри агрегатной функции.

Stas
11.05.2018
12:27:56

Michal
11.05.2018
12:28:21
Ну так она не уйдет в null таким образом.

Stas
11.05.2018
12:28:34
на старой версии прекрасно уходит

Michal
11.05.2018
12:28:35
mysql> select sum(a) from (select NULL a union all select 1) x;
+--------+
| sum(a) |
+--------+
| 1 |
+--------+
1 row in set (0.03 sec)
Ms SQL: http://sqlfiddle.com/#!18/9eecb/17225

Denis
11.05.2018
12:29:14
@milovidov_an
Похоже на сложных ключах партиционирования КХ читает те партиции, которые читать не нужно
CREATE TABLE test.testy(d Date, n Int64, k Int64)
ENGINE = MergeTree Partition by (n, toStartOfMonth(d)) Order by (k);
insert into test.testy select toDate('2018-05-01') as d, 33 n, 0 from numbers(1);
insert into test.testy select toDate('2018-05-03') as d, 33 n, 0 from numbers(20000000);
SELECT count() FROM test.testy PREWHERE (n = -1);
0 rows in set. Elapsed: 0.010 sec. Processed 19.92 million rows, 159.38 MB (1.92 billion rows/s., 15.34 GB/s.)
в реальном проде миллиарды читаются из совершенно "левых" партиций, причем иной порядок в Partition by (toStartOfMonth(d), n) ничего не исправляет.
https://github.com/yandex/ClickHouse/issues/2342


Michal
11.05.2018
12:29:14
Postgres: http://sqlfiddle.com/#!17/9eecb/14140
Если хотите чтоб при наличии единственного NULL в группе - вся группа вернула NULL, то нужно состряпать что-то типа:
:) select CASE WHEN anyIf(1, a IS NULL) THEN NULL ELSE sum(a) END from (select NULL a union all select 1) x;
Или (чуть короче):
select if( anyIf(1, a IS NULL), NULL, sum(a) ) from (select NULL a union all select 5) x;

Google

Stas
11.05.2018
12:42:53
А не известно случаем, то, что в groupArray нельзя положить INT и NULL - это баг или фича?

Michal
11.05.2018
12:43:56
Нужно чтоб был общий тип данных.
ЕМНИП там нужно явно все кастовать - тогда проглотит

Stas
11.05.2018
12:45:33

Michal
11.05.2018
12:46:38
хотя groupArray и так похоже пропускает Null.

Stas
11.05.2018
12:50:38

Michal
11.05.2018
12:53:22
Я в том смысле что groupArray не собирает в таблицу NULL'ы при группировке. А про этот эксепшен - есть Array(Nullable(Int64)) но не бывает Nullable(Array(Int64))
Таблица не может быть Null. Она может быть или пустая или содержать Null.

Stas
11.05.2018
13:00:38
а если я оберну в groupArray(ifNull(counter, 0))- ок
что то у меня совсем голова кипит от этого...
мда, убрал remote из поля from и ровно тот же запрос прекрасно заработал.... ну я даже не знаю

Michal
11.05.2018
13:22:47
А можете показать запрос?

Vasily
11.05.2018
13:36:12
Приветствую, подскажите, пожалуйста, если ли какая-то возможность оптимизировать запрос (сколько определенных действий выполнили люди пришедшие по конкретной utm)?
SELECT
countIf((url = '/registration') AND (response = 200)) AS cnt_reg,
countIf((url = '/order') AND (response = 200)) AS cnt_order
FROM events
WHERE user_uid IN
(
SELECT user_uid
FROM events
WHERE utm_source = 'vk'
)
а то он какой-то слишком тяжелый получается, 3 секунды на 15млн строк

Konstantin
11.05.2018
13:38:00


Vasily
11.05.2018
13:40:15
все, запрос вообще неверный получился, потому что время событий не учитывалось, а с sequenceMatch вообще беда получилась:
SELECT count()
FROM
(
SELECT user_uid
FROM events
GROUP BY user_uid
HAVING sequenceMatch('(?1)(?2)')(toDateTime(event_time), utm_source = 'vk', url = '/order')
)
вот такая штука выполняется столько, что ждать устанешь
1 rows in set. Elapsed: 69.224 sec. Processed 15.58 million rows, 2.40 GB (225.10 thousand rows/s., 34.65 MB/s.)


Michal
11.05.2018
14:03:49
все, запрос вообще неверный получился, потому что время событий не учитывалось, а с sequenceMatch вообще беда получилась:
SELECT count()
FROM
(
SELECT user_uid
FROM events
GROUP BY user_uid
HAVING sequenceMatch('(?1)(?2)')(toDateTime(event_time), utm_source = 'vk', url = '/order')
)
вот такая штука выполняется столько, что ждать устанешь
А так?
SELECT
countIf(1, step1_time != toDateTime(0)) AS registrations,
countIf(1, step2_time != toDateTime(0)) AS orders_after_registrations
FROM
(
SELECT
user_uid,
minIf(event_time, url = '/registration' AND response = 200) AS step1_time,
arrayFilter(time -> ((step1_time != toDateTime(0)) AND (time > step1_time)), groupArrayIf(event_time, url = '/order' AND response = 200 ))[0] AS step2_time
FROM events
GROUP BY user_uid
HAVING anyIf(1, utm_source = 'vk' )
)

Google

Michal
11.05.2018
14:04:49
ага, только там нужно чтоб utm_source было в начале (сейчас может быть где угодно)

Vasily
11.05.2018
14:05:05
ух ты, ну теперь дома доберусь - проверю)
спасибо!

Alexander
11.05.2018
14:25:31
Всем привет!
Подскажите, пожалуйста, а материлизованные вьюхи работают со вложенными селектами?

Tima
11.05.2018
14:26:08
С JOIN к другим таблицам точно не рабоет

Alexander
11.05.2018
14:27:24
конструкция вида select max(a) from (select avg(b) as a from (... from table))

George
11.05.2018
14:42:29
Очень глупый вопрос: а где и как хранить версию схемы базы данных для самого clickhouse'а? Я думал, что подойдёт отдельная таблица, но т.к. update'ы не поддерживаются, то пометить была миграция или нет не получится.


Michal
11.05.2018
14:42:42
ух ты, ну теперь дома доберусь - проверю)
Так правильно (три шага друг за другом):
SELECT
countIf(1, step1_time != toDateTime(0)) AS vk_entry,
countIf(1, step2_time != toDateTime(0)) AS registrations_after_vk_entry,
countIf(1, step3_time != toDateTime(0)) AS orders_after_registrations_after_vk_entry
FROM
(
SELECT
user_uid,
minIf(event_time, utm_source = 'vk') AS step1_time,
arrayReduce('min', arrayFilter(time -> ((step1_time != toDateTime(0)) AND (time > step1_time)), groupArrayIf(event_time, url = '/registration'))) AS step2_time,
arrayFilter(time -> ((step2_time != toDateTime(0)) AND (time > step2_time)), groupArrayIf(event_time, url = '/order'))[1] AS step3_time
FROM events
WHERE response = 200 and ( utm_source = 'vk' OR url in ('/registration', '/order') )
GROUP BY user_uid
)


George
11.05.2018
14:44:36
А как же транзакции? Типа, "начали миграцию", "закончили миграцию"? Так же доп. строчками в лог?

Michal
11.05.2018
14:44:54
угу.
тут гляньте ещё: https://github.com/filimonov/ClickHouse/wiki/Clickhouse-database-schema-migrations
в go-migrate как раз такой подход и реализован

George
11.05.2018
14:46:00
Можно. Вообще, немного не хватает update'ов для мелочи. Я понимаю, что это не профиль clickhouse'а, но простенький движок для маленьких данных (типа конфигурации), хоть даже и на sqlight'е был бы ценен.

Michal
11.05.2018
15:10:50
При небольших таблицах игнорирование удаленных / обновленных версий той же строки - тривиально, и практически не ощутимо. Но да, запросы и схема таблицы для имитации update/delete - режут глаза своей костыльностью, по сравнению с нормальными UPDATE / DELETE.
:)

Denis
11.05.2018
15:30:09

Michael
11.05.2018
15:45:07
Добрый вечер. Подскажите, как добавить ClickHouse JDBC в gradle-проект?

papa
11.05.2018
15:47:13
https://mvnrepository.com/artifact/ru.yandex.clickhouse/clickhouse-jdbc/0.1.39
compile group: 'ru.yandex.clickhouse', name: 'clickhouse-jdbc', version: '0.1.39'

Google

Denis
11.05.2018
15:49:07
мда,
SELECT count() FROM test.testy WHERE (n = 34 );
1 rows in set. Elapsed: 0.002 sec.
optimize table test.testy;
SELECT count() FROM test.testy WHERE (n = 34 );
1 rows in set. Elapsed: 0.007 sec. Processed 10.00 million rows, 80.00 MB (1.38 billion rows/s., 11.07 GB/s.)

Michael
11.05.2018
15:56:18

Kirill
11.05.2018
16:07:05

Denis
11.05.2018
16:10:55

Kirill
11.05.2018
16:15:19
mysql() при наличии более двух колонок в WHERE начинает выгружать всю таблицу ? 0_o
WHERE updated_at > '2018-05-11 14:55:03' OR id > 12313412341

Александр
11.05.2018
16:18:00
С криками, что колонка не существует

Kirill
11.05.2018
16:36:36
Подскажите пожалуйста. Допустим есть колонка Int8. Но при суммировании значений при запросе - сумма выходит за рамки Int8. Clickhouse обрежет ее до макс. значения Int8 или преобразует в нужный тип Int32 или Int64?
Или это нужно в явном виде задать чем-то вроде type casting'а?

antuan
11.05.2018
16:39:39
:) select cast(10000 as UInt8) + cast(9876 as UInt8);
SELECT CAST(10000 AS UInt8) + CAST(9876 AS UInt8)
┌─plus(CAST(10000, \'UInt8\'), CAST(9876, \'UInt8\'))─┐
│ 164 │
└─────────────────────────────────────────────────────┘
просто в качестве догадки
опс, нет, фиговая догадка

Nikolai
11.05.2018
16:40:22

antuan
11.05.2018
16:40:51
:) select cast(250 as UInt8) + cast(255 as UInt8);
SELECT CAST(250 AS UInt8) + CAST(255 AS UInt8)
┌─plus(CAST(250, \'UInt8\'), CAST(255, \'UInt8\'))─┐
│ 505 │
└──────────────────────────────────────────────────┘

Nikolai
11.05.2018
16:41:53
сложение хитрое. оно возвращает общий тип, в который влезает сумма
можно вызвать toTypeName и проверить, какой получится результат

antuan
11.05.2018
16:42:48
:) select cast(255 as UInt8) * 100;
SELECT CAST(255 AS UInt8) * 100
┌─multiply(CAST(255, \'UInt8\'), 100)─┐
│ 25500 │
└─────────────────────────────────────┘
1 rows in set. Elapsed: 0.003 sec.
:) select cast(255 as Int8) * 100;
SELECT CAST(255 AS Int8) * 100
┌─multiply(CAST(255, \'Int8\'), 100)─┐
│ -100 │
└────────────────────────────────────┘