Оптимизация загрузки новых записей

Теперь новые записи сначала поступают в буфер в памяти и по достижению ограничений количества записей / размера отправляются в основную таблицу.

Также сброс без каких-либо условий на ресурсы выполняется раз в минуту.

Данный подход позволит оптимизировать операции записи в базу ClickHouse и избежать ошибок при множественной вставке данных в таблицы с движком Merge.
This commit is contained in:
YPermitin
2021-04-11 00:31:34 +05:00
parent 4c687e8fe7
commit 98a2266e08
4 changed files with 42 additions and 15 deletions
@@ -33,6 +33,10 @@ namespace YY.TechJournalExportAssistant.ClickHouse
_connection.Open();
var cmdDDL = _connection.CreateCommand();
cmdDDL.CommandText = Resource.Query_CreateTable_EventDataStorage;
cmdDDL.ExecuteNonQuery();
cmdDDL.CommandText = Resource.Query_CreateTable_LogFilesStorage;
cmdDDL.ExecuteNonQuery();
cmdDDL.CommandText = Resource.Query_CreateTable_EventData;
cmdDDL.ExecuteNonQuery();
cmdDDL.CommandText = Resource.Query_CreateTable_LogFiles;
@@ -244,12 +248,12 @@ namespace YY.TechJournalExportAssistant.ClickHouse
{
var commandRemoveArchiveLogInfo = _connection.CreateCommand();
commandRemoveArchiveLogInfo.CommandText =
@"ALTER TABLE LogFiles DELETE
@"ALTER TABLE LogFilesStorage DELETE
WHERE TechJournalLog = {techJournalLog:String}
AND DirectoryName = {directoryName:String}
AND Id < (
SELECT MAX(Id) AS LastId
FROM LogFiles lf
FROM LogFilesStorage lf
WHERE TechJournalLog = {techJournalLog:String}
AND DirectoryName = {directoryName:String}
)";
@@ -61,7 +61,16 @@ namespace YY.TechJournalExportAssistant.ClickHouse {
}
/// <summary>
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS EventData
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS EventData AS EventDataStorage ENGINE = Buffer(currentDatabase(), EventDataStorage, 16, 10, 60, 100000, 1000000, 10000000, 100000000).
/// </summary>
internal static string Query_CreateTable_EventData {
get {
return ResourceManager.GetString("Query_CreateTable_EventData", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS EventDataStorage
///(
/// TechJournalLog LowCardinality(String),
/// DirectoryName LowCardinality(String),
@@ -73,17 +82,25 @@ namespace YY.TechJournalExportAssistant.ClickHouse {
/// DurationSec Int64 Codec(DoubleDelta, LZ4),
/// EventName LowCardinality(String),
/// ServerContextName LowCardinality(String),
/// ProcessName LowCardinality(String),
/// S [остаток строки не уместился]&quot;;.
/// ProcessName LowCardinality(String), [остаток строки не уместился]&quot;;.
/// </summary>
internal static string Query_CreateTable_EventData {
internal static string Query_CreateTable_EventDataStorage {
get {
return ResourceManager.GetString("Query_CreateTable_EventData", resourceCulture);
return ResourceManager.GetString("Query_CreateTable_EventDataStorage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS LogFiles
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS LogFiles AS LogFilesStorage ENGINE = Buffer(currentDatabase(), LogFilesStorage, 16, 10, 60, 100000, 1000000, 10000000, 100000000).
/// </summary>
internal static string Query_CreateTable_LogFiles {
get {
return ResourceManager.GetString("Query_CreateTable_LogFiles", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на CREATE TABLE IF NOT EXISTS LogFilesStorage
///(
/// TechJournalLog LowCardinality(String),
/// DirectoryName LowCardinality(String),
@@ -97,12 +114,11 @@ namespace YY.TechJournalExportAssistant.ClickHouse {
///)
///engine = MergeTree()
///PARTITION BY toYYYYMM(CreateDate)
///PRIMARY KEY CreateDate
///OR [остаток строки не уместился]&quot;;.
///PRIMARY KEY CreateD [остаток строки не уместился]&quot;;.
/// </summary>
internal static string Query_CreateTable_LogFiles {
internal static string Query_CreateTable_LogFilesStorage {
get {
return ResourceManager.GetString("Query_CreateTable_LogFiles", resourceCulture);
return ResourceManager.GetString("Query_CreateTable_LogFilesStorage", resourceCulture);
}
}
}
@@ -118,7 +118,11 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Query_CreateTable_EventData" xml:space="preserve">
<value>CREATE TABLE IF NOT EXISTS EventData
<value>CREATE TABLE IF NOT EXISTS EventData AS EventDataStorage ENGINE = Buffer(currentDatabase(), EventDataStorage, 16, 10, 60, 100000, 1000000, 10000000, 100000000)</value>
<comment>Создание буфера для новых данных технологического журнала</comment>
</data>
<data name="Query_CreateTable_EventDataStorage" xml:space="preserve">
<value>CREATE TABLE IF NOT EXISTS EventDataStorage
(
TechJournalLog LowCardinality(String),
DirectoryName LowCardinality(String),
@@ -164,7 +168,10 @@ SETTINGS index_granularity = 8192;</value>
<comment>Создание таблицы для хранения данных технологического журнала</comment>
</data>
<data name="Query_CreateTable_LogFiles" xml:space="preserve">
<value>CREATE TABLE IF NOT EXISTS LogFiles
<value>CREATE TABLE IF NOT EXISTS LogFiles AS LogFilesStorage ENGINE = Buffer(currentDatabase(), LogFilesStorage, 16, 10, 60, 100000, 1000000, 10000000, 100000000)</value>
</data>
<data name="Query_CreateTable_LogFilesStorage" xml:space="preserve">
<value>CREATE TABLE IF NOT EXISTS LogFilesStorage
(
TechJournalLog LowCardinality(String),
DirectoryName LowCardinality(String),
@@ -18,7 +18,7 @@ namespace YY.TechJournalExportAssistant.ClickHouse
private TechJournalLogBase _techJournalLog;
private readonly string _connectionString;
private TechJournalPosition _lastTechJournalFilePosition;
private int _stepsToClearLogFiles = 1000;
private int _stepsToClearLogFiles = 10000;
private int _currentStepToClearLogFiles;
#endregion