
Andrey
06.04.2017
15:53:58
Кто нибудь настраивал словари через ODBC?


Nikita
06.04.2017
15:55:27
Как я делал с постгресным драйвером:
sudo apt-get install -y unixodbc
sudo apt-get install -y odbcinst
sudo apt-get install -y odbc-postgresql
В /etc/odbc.ini:
[DEFAULT]
Driver = myconnection
[myconnection]
Description = PostgreSQL connection to norma
Driver = PostgreSQL Unicode
Database = norma
Servername = 10.... (твой хост)
UserName = uname
Password = pwd
Port = 5432
Protocol = 9.3
ReadOnly = No
RowVersioning = No
ShowSystemTables = No
ConnSettings =
<dictionary>
<name>table_name</name>
<source>
<odbc>
<table>postgresql_table</table>
<connection_string>DSN=myconnection</connection_string> <!— может потребоваться UID=norma;PWD=norma;, но по идее не должно —->
</odbc>
</source>
<lifetime>
<min>300</min>
<max>360</max>
</lifetime>
<layout>
<flat/>
</layout>
<structure>
<id>
<name>id</name>
</id>
<attribute>
<name>some_column</name>
<type>Int32</type>
<null_value>-1</null_value>
</attribute>
...
</structure>
</dictionary>

Alexey
06.04.2017
15:55:45

Andrey
06.04.2017
16:03:14

Google

Andrey
06.04.2017
16:03:28

Vitaliy
06.04.2017
16:53:24

Maksim
06.04.2017
16:53:55
/var/www/html/build# cat data.bin | POST 'http://localhost:8123/?query=INSERT INTO statistics.test FORMAT Native'
Poco::Exception. Code: 1000, e.code() = 0, e.displayText() = Exception: Too large string size., e.what() = Exception
каким еще способом можно импортнуть дамп ?

Alexey
06.04.2017
17:27:03
А опцию decompress не забыли?

Maksim
06.04.2017
17:29:23

Andrey
06.04.2017
18:00:24
Ребят, а если используется функция работы с датой над полем date, clickhouse перестает использовать индекс и идет фуллсканить?
например так:
where
toYear(clickhouse_date) = 2016 and toMonth(clickhouse_date) in (2,9)

Maksim
06.04.2017
18:04:52
Может кто скажет как схему выгрузить таблицы?

Ivan
06.04.2017
18:05:19

Ilya
06.04.2017
18:05:25

Владимир
06.04.2017
18:05:33
https://clickhouse.yandex/reference_ru.html#SHOW CREATE TABLE

Maksim
06.04.2017
18:12:39
https://clickhouse.yandex/reference_ru.html#SHOW CREATE TABLE
SHOW TABLES FROM statistics LIKE 'banner_history_segments' INTO OUTFILE test.txt
Code: 62, e.displayText() = DB::Exception: Syntax error: failed at position 73 (line 1, col 73): test.txt
/*TABIX_QUERY_ID_vKOdebem13K6Ub8_()*/, expected opening single quote, e.what() = DB::Exception\n
как в файл выгрузить схему чтобы потом её заново восстановить ?

Google

Владимир
06.04.2017
18:14:32
А скопировать из консоли религия не позволяет?)

Maksim
06.04.2017
18:14:40
show create table table_name вот это самое то
и тупо скинуть в файлик )

Alexey
06.04.2017
18:24:56


Andrey
06.04.2017
18:28:26
Индекс всё-равно будет использоваться.
В чем тогда может быть ошика?
Processed rows разный. И для первого запроса processed = количеству
:) select count(*) from some_table where toYear(clickhouse_date) = 2016 and toMonth(clickhouse_date) in (10,9)
┌──count()─┐
│ 43349387 │
└──────────┘
→ Progress: 252.86 million rows, 505.71 MB (1.28 billion rows/s., 2.57 GB/s.)
1 rows in set. Elapsed: 0.197 sec. Processed 252.86 million rows, 505.71 MB (1.28 billion rows/s., 2.57 GB/s.)
:) select count(*) from some_table where clickhouse_date between '2016-09-01' and '2016-10-30'
┌──count()─┐
│ 42621496 │
└──────────┘
1 rows in set. Elapsed: 0.023 sec. Processed 43.35 million rows, 86.70 MB (1.88 billion rows/s., 3.76 GB/s.)

Alexey
06.04.2017
18:39:02
Жаль, почему-то в этом случае плохо сработало. Использование индекса, в принципе, поддерживается для такого вида функций. Подробнее сейчас не могу сказать.

Владимир
06.04.2017
18:45:14
в КХ индексы работают не так, как в мускуле
они отвечают за сегментирование данных на чанки, чтобы кх при запросе просто откидывал ненужные чанки, ускоряя сканирование. т.е. если у нас MergeTree с индексом date - будут эффективно выполняться запросы на ограниченный набор дат, за счёт того что чанки с датами в другом диапазоне просто не будут читаться. по идее, он должен грамотно учитывать функции, по крайней мере у меня во всех запросах используется фильтр toDate(eventDate) BETWEEN 'someDataStr' AND '.....' и это не вызывает проблем

Vladimir
06.04.2017
18:53:02
Либо преобразование даты не отрабатывает. Либо одно из двух (с)

Владимир
06.04.2017
18:53:43
Он в первом варианте, скорее всего сначала выполнил сканирование по первому условию, а потом отфильтровал по второму.
Во втором случае, запрос был более однозначным

Vladimir
06.04.2017
18:54:10
Такое не должно быть.

Andrey
06.04.2017
18:54:13
Vladimir В октябре 31 день, может поэтому?

Владимир
06.04.2017
18:54:18
Возможно, из за in(9,10)
Оптимизатор мог решить, что выборку IN не стоит делать в PREWHERE
Кстати, а если явно указать PREWHERE в первом варианте?

Vladimir
06.04.2017
18:55:16
А где оно?

Владимир
06.04.2017
18:55:47
https://clickhouse.yandex/reference_ru.html#Секция PREWHERE

Google

Vladimir
06.04.2017
18:56:09
Не думаю что из за этого

Andrey
06.04.2017
18:56:42
Ребят, запросы же разные. Один день выпадает там где between

Vladimir
06.04.2017
18:56:47
Аа точно
Все гениальное просто.

Andrey
06.04.2017
18:58:09
Не, ребят , проблема не в одном дне

Andrey
06.04.2017
18:59:13
Ну, почему разное число обработанных строк — непонятно, видимо внутренняя кухня. А результат разный — из-за одного дня.

Владимир
06.04.2017
18:59:14
а clickhouse-client же показывает, как он оптимизировал запрос?
Я подозреваю что для select count(*) from some_table where toYear(clickhouse_date) = 2016 будет: Processed 252.86 million rows
"Если настройка optimize_move_to_prewhere выставлена в 1, то при отсутствии PREWHERE, система будет автоматически переносить части выражений из WHERE в PREWHERE согласно некоторой эвристике."

Andrey
06.04.2017
19:05:25
проблема в IN
:) select count(*) from osa_posdata where (toMonth(clickhouse_date) = 9 or toMonth(clickhouse_date) =10) and toYear(clickhouse_date) = 2016
┌──count()─┐
│ 43349387 │
└──────────┘
1 rows in set. Elapsed: 0.045 sec. Processed 43.35 million rows, 86.70 MB (971.86 million rows/s., 1.94 GB/s.)
:) select count(*) from osa_posdata where toMonth(clickhouse_date) in(10,9) and toYear(clickhouse_date) = 2016
┌──count()─┐
│ 43349387 │
└──────────┘
1 rows in set. Elapsed: 0.159 sec. Processed 252.86 million rows, 505.71 MB (1.59 billion rows/s., 3.18 GB/s.)

Владимир
06.04.2017
19:05:32
И эта "некоторая эвристика" в данном случае могла посчитать, что нужно сначала выполнить запрос по "toYear(clickhouse_date) = 2016" и уже в полученных данных провести фильтрацию по "toMonth(clickhouse_date) in (10,9)"
Оптимизаторы не любят IN, это да
Но если не предполагается делать IN(7,11) например, то почему бы не взять BETWEEN ? Оптимизатор его понимает значительно лучше

Andrey
06.04.2017
19:08:32
Не проблема. Чуть больше кода на стороне бекенда. Я просто натолкнулся на странность. Вот и написал.
Кстати вопрос, как оптимальнее сравнивать периоды. Через sum и join или через sumif и group by?

Владимир
06.04.2017
19:10:58
Я предпочитаю сравнивать уже в коде, поскольку бывают разные условия, соответственно два запроса
Но это уже на вкус и цвет)

Alexey
06.04.2017
19:11:09
Мы в Метрике сравниваем вторым способом:
- в WHERE указывается OR для обеих периодов,
а затем все агрегатные функции считаются с условиями для одного и для второго периода.

Google

Andrey
06.04.2017
19:15:16

Владимир
06.04.2017
19:18:02
Блин. Я не приведу пример, сам сейчас представить не могу кейс) Думаю, основная причина в том, что я бэкендщик, а не дба, мне проще выдернуть данные и уже в коде с ними работать)

Andrey
06.04.2017
19:19:31

Владимир
06.04.2017
19:20:59
При следующем рефакторинге как раз будет повод проверить)

Andrey
06.04.2017
19:21:50
оно конечно еще сильно зависит от количества данных. Если там 5 строк, то не важно где считать. А у нас просто выхлоп большой(относительно).

Владимир
06.04.2017
19:24:43
У меня данные на выходе обычно уже сагрегированы, и приходится сравнивать относительно небольшие массивы, так что к производительности кода претензий нет

Andrey
06.04.2017
19:28:44
ну тогда да, тут просто как удобнее.
А я правильно понимаю что вот тут агрегация заняла 8 сек?
2017.04.06 22:27:01.924306 [ 967 ] <Trace> Aggregator: Merging aggregated data
2017.04.06 22:27:02.190420 [ 967 ] <Trace> Aggregator: Aggregation method: keys256
2017.04.06 22:27:10.879413 [ 967 ] <Trace> Aggregator: Aggregated. 36840327 to 921756 rows (from 1018.877 MiB) in 13.021 sec. (2829352.510 rows/sec., 78.250 MiB/sec.)
2017.04.06 22:27:10.879509 [ 967 ] <Trace> Aggregator: Merging aggregated data

papa
06.04.2017
19:35:14

Владимир
06.04.2017
19:38:17
Сначала в PREWHERE выбрать нужные данные в колонки с разными именами, а потом в WHERE доагрегировать их, смерджив периоды

Andrey
06.04.2017
19:38:24

papa
06.04.2017
19:39:01
а, если toMonth(), то у вас во-первых some_field не в агрегате, а во вторых какая-то матрица шахматная получится,

Владимир
06.04.2017
19:39:26
ПОдзапросом по идее можно

Andrey
06.04.2017
19:39:49

Владимир
06.04.2017
19:40:35
Я сейчас теоретизирую)
с PREWHERE не экспериментировал пока, а с подзапросом делал подобные выборки

Andrey
06.04.2017
19:41:26

papa
06.04.2017
19:42:13
отчет в метрике делает запрос похожий на ваш, только в нем group by some_field

Andrey
06.04.2017
19:42:39

Google

Andrey
06.04.2017
19:43:04
а вы с PREWHERE делаете что нибудь? или верите в оптимизатор?

Владимир
06.04.2017
19:43:20
Вначале одним запросом мы получаем что-то типа row1(day=1, sum1=0, sum2=100), row2(day=1, sum1=66, sum2=0), ... и так по каждому дню, а потом группируем по day

papa
06.04.2017
19:43:26
если some_field это не время, то получится примерно то , что надо. если время, то будут нули в непересекающихся местах.

Andrey
06.04.2017
19:44:04
у нас аналитика чеков. И сравниваем продажи товара по периодам.
Т.е. получается
товар | количество в первом периоде | количество во втором

papa
06.04.2017
19:45:25

Andrey
06.04.2017
19:46:45
>подтянул некую оценку кардинальности колонок
вот сейчас сложно было)

papa
06.04.2017
19:47:41
>подтянул некую оценку кардинальности колонок
вот сейчас сложно было)
для каждой колонки есть распределение количества ее значений, в дне, в нескольких днях по различным например клиентам. из этого во-первых можно оценивать "среднюю в вакууме" тяжесть запроса - количество ключей в group by, доля данных которая останется после фильтра column=value, итд. такие метаданные, которые оптимизатор бд обычно собирает в индексы или еще куда чтобы использовать при оптимизации.
но мы верим в prewhere в частности и в clickhouse в целом.


Владимир
06.04.2017
19:51:07
Хм. Вот кстати. Как в запросе для каждого запрашиваемого числового значения получить его процентное отношение к прошлому периоду? т.е., на сколько процентов упали\поднялись посещения\клики\продажи за этот день относительно вчерашнего\на прошлой неделе\в прошлом месяце?

Andrey
06.04.2017
19:51:55

papa
06.04.2017
19:53:47
каждого запрашиваемого - это как? если я правильно понял вопрос, то мы делаем два набора вызовов агрегатных функций.

Владимир
06.04.2017
19:54:56
Хм, действительно) Сначала запрашиваем два набора, преагрегируем их с разными именами, вычисляем процентное соотношение и доагрегируем по нужному ключу...
Надо будет попробовать запрос написать на реальных данных, посмотреть как отрабатывает

Иван
06.04.2017
21:54:15
Доброго времени суток! Есть ли разница в порядке указания колонок в индексе? Т.е если создать таблицу с индексом (c1, c2). То при при фильтрации по полю c2 будет ли использоваться индекс? Или он будет использоваться только при фильтрации по c1, по (c1 и с2) ?
Сделал таблички типа ReplacingMergeTree с индексами (с1,с2) и (с2,с1) соответственно. залил в них одинаковые данные. Запрос с фильтром по с1 был значительно менее ресурсоемким к первой табличке (где с1 указано в индексе на первой позиции), а запрос по с2 соответственно ко второй таблице. Осознал, что не понимаю как работают индексы в CH, прокомментируйте пожалуйста.

papa
06.04.2017
22:23:07
а распределение у c1 c2 какое?

Sergey
07.04.2017
08:11:20
Добрый день! Подскажите, кто-то собирал ODBC-драйвер под RHEL/Centos 6 ?

Andrey
07.04.2017
08:18:47

Sergey
07.04.2017
08:21:19
не совсем, как минимум в rhel6 нет gcc5