提交 58ea3b10 编写于 作者: M Michael Kolupaev

Merge

上级 96fb6da0
#pragma once
#include <DB/Core/Names.h>
#include <DB/Core/NamesAndTypes.h>
#include <DB/Core/Exception.h>
#include <DB/Core/Block.h>
#include <DB/Parsers/ASTAlterQuery.h>
namespace DB
{
class Context;
/** Описание столбцов таблицы.
*/
class IColumnsDeclaration
{
public:
/// Имя таблицы. Ни на что не влияет, используется только для сообщений об ошибках.
virtual std::string getTableName() const { return ""; }
/** Получить список имён и типов столбцов таблицы, только невиртуальные.
*/
virtual const NamesAndTypesList & getColumnsList() const = 0;
/** Получить описание реального (невиртуального) столбца по его имени.
*/
virtual NameAndTypePair getRealColumn(const String & column_name) const;
/** Присутствует ли реальный (невиртуальный) столбец с таким именем.
*/
virtual bool hasRealColumn(const String & column_name) const;
/** Получить описание любого столбца по его имени.
*/
virtual NameAndTypePair getColumn(const String & column_name) const;
/** Присутствует ли столбец с таким именем.
*/
virtual bool hasColumn(const String & column_name) const;
const DataTypePtr getDataTypeByName(const String & column_name) const;
/** То же самое, но в виде блока-образца.
*/
Block getSampleBlock() const;
/** Проверить, что все запрошенные имена есть в таблице и заданы корректно.
* (список имён не пустой и имена не повторяются)
*/
void check(const Names & column_names) const;
/** Проверить, что блок с данными для записи содержит все столбцы таблицы с правильными типами,
* содержит только столбцы таблицы, и все столбцы различны.
* Если need_all, еще проверяет, что все столбцы таблицы есть в блоке.
*/
void check(const Block & block, bool need_all = false) const;
/// реализация alter, модифицирующая список столбцов.
static void alterColumns(const ASTAlterQuery::Parameters & params, NamesAndTypesListPtr & columns, const Context & context);
virtual ~IColumnsDeclaration() {}
};
}
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
#include <DB/Parsers/ASTAlterQuery.h> #include <DB/Parsers/ASTAlterQuery.h>
#include <DB/Interpreters/Settings.h> #include <DB/Interpreters/Settings.h>
#include <DB/Storages/StoragePtr.h> #include <DB/Storages/StoragePtr.h>
#include "DatabaseDropper.h" #include <DB/Storages/IColumnsDeclaration.h>
#include <DB/Storages/DatabaseDropper.h>
#include <Poco/File.h> #include <Poco/File.h>
...@@ -30,41 +31,15 @@ class Context; ...@@ -30,41 +31,15 @@ class Context;
* - структура хранения данных (сжатие, etc.) * - структура хранения данных (сжатие, etc.)
* - конкуррентный доступ к данным (блокировки, etc.) * - конкуррентный доступ к данным (блокировки, etc.)
*/ */
class IStorage : private boost::noncopyable class IStorage : private boost::noncopyable, public IColumnsDeclaration
{ {
public: public:
/// Основное имя типа таблицы (например, StorageWithoutKey). /// Основное имя типа таблицы (например, StorageMergeTree).
virtual std::string getName() const = 0; virtual std::string getName() const = 0;
/// Имя самой таблицы (например, hits) /// Имя самой таблицы (например, hits)
virtual std::string getTableName() const = 0; virtual std::string getTableName() const = 0;
/** Получить список имён и типов столбцов таблицы, только невиртуальные.
*/
virtual const NamesAndTypesList & getColumnsList() const = 0;
/** Получить описание реального (невиртуального) столбца по его имени.
*/
virtual NameAndTypePair getRealColumn(const String & column_name) const;
/** Присутствует ли реальный (невиртуальный) столбец с таким именем.
*/
virtual bool hasRealColumn(const String & column_name) const;
/** Получить описание любого столбца по его имени.
*/
virtual NameAndTypePair getColumn(const String & column_name) const;
/** Присутствует ли столбец с таким именем.
*/
virtual bool hasColumn(const String & column_name) const;
const DataTypePtr getDataTypeByName(const String & column_name) const;
/** То же самое, но в виде блока-образца.
*/
Block getSampleBlock() const;
/** Возвращает true, если хранилище получает данные с удалённого сервера или серверов. /** Возвращает true, если хранилище получает данные с удалённого сервера или серверов.
*/ */
virtual bool isRemote() const { return false; } virtual bool isRemote() const { return false; }
...@@ -172,19 +147,6 @@ public: ...@@ -172,19 +147,6 @@ public:
*/ */
virtual void shutdown() {} virtual void shutdown() {}
virtual ~IStorage() {}
/** Проверить, что все запрошенные имена есть в таблице и заданы корректно.
* (список имён не пустой и имена не повторяются)
*/
void check(const Names & column_names) const;
/** Проверить, что блок с данными для записи содержит все столбцы таблицы с правильными типами,
* содержит только столбцы таблицы, и все столбцы различны.
* Если need_all, еще проверяет, что все столбцы таблицы есть в блоке.
*/
void check(const Block & block, bool need_all = false) const;
/** Возвращает владеющий указатель на себя. /** Возвращает владеющий указатель на себя.
*/ */
StoragePtr thisPtr() StoragePtr thisPtr()
...@@ -214,8 +176,6 @@ public: ...@@ -214,8 +176,6 @@ public:
protected: protected:
IStorage() : drop_on_destroy(false) {} IStorage() : drop_on_destroy(false) {}
/// реализация alter, модифицирующая список столбцов.
void alterColumns(const ASTAlterQuery::Parameters & params, NamesAndTypesListPtr & columns, const Context & context) const;
private: private:
boost::weak_ptr<StoragePtr::Wrapper> this_ptr; boost::weak_ptr<StoragePtr::Wrapper> this_ptr;
}; };
......
#pragma once #pragma once
#include <DB/DataStreams/IProfilingBlockInputStream.h> #include <DB/DataStreams/IProfilingBlockInputStream.h>
#include <DB/Storages/StorageMergeTree.h> #include <DB/Storages/MergeTree/MergeTreeData.h>
#include <DB/Storages/MergeTree/PKCondition.h> #include <DB/Storages/MergeTree/PKCondition.h>
#include <DB/Storages/MergeTree/MergeTreeReader.h> #include <DB/Storages/MergeTree/MergeTreeReader.h>
...@@ -18,7 +18,7 @@ public: ...@@ -18,7 +18,7 @@ public:
/// (например, поток, сливаящий куски). В таком случае сам storage должен следить, чтобы не удалить данные, пока их читают. /// (например, поток, сливаящий куски). В таком случае сам storage должен следить, чтобы не удалить данные, пока их читают.
MergeTreeBlockInputStream(const String & path_, /// Путь к куску MergeTreeBlockInputStream(const String & path_, /// Путь к куску
size_t block_size_, const Names & column_names_, size_t block_size_, const Names & column_names_,
StorageMergeTree & storage_, const StorageMergeTree::DataPartPtr & owned_data_part_, MergeTreeData & storage_, const MergeTreeData::DataPartPtr & owned_data_part_,
const MarkRanges & mark_ranges_, StoragePtr owned_storage, bool use_uncompressed_cache_, const MarkRanges & mark_ranges_, StoragePtr owned_storage, bool use_uncompressed_cache_,
ExpressionActionsPtr prewhere_actions_, String prewhere_column_) ExpressionActionsPtr prewhere_actions_, String prewhere_column_)
: IProfilingBlockInputStream(owned_storage), : IProfilingBlockInputStream(owned_storage),
...@@ -74,8 +74,8 @@ public: ...@@ -74,8 +74,8 @@ public:
/// Получает набор диапазонов засечек, вне которых не могут находиться ключи из заданного диапазона. /// Получает набор диапазонов засечек, вне которых не могут находиться ключи из заданного диапазона.
static MarkRanges markRangesFromPkRange( static MarkRanges markRangesFromPkRange(
const StorageMergeTree::DataPart::Index & index, const MergeTreeData::DataPart::Index & index,
StorageMergeTree & storage, MergeTreeData & storage,
PKCondition & key_condition) PKCondition & key_condition)
{ {
MarkRanges res; MarkRanges res;
...@@ -321,8 +321,8 @@ private: ...@@ -321,8 +321,8 @@ private:
Names column_names; Names column_names;
NameSet column_name_set; NameSet column_name_set;
Names pre_column_names; Names pre_column_names;
StorageMergeTree & storage; MergeTreeData & storage;
const StorageMergeTree::DataPartPtr owned_data_part; /// Кусок не будет удалён, пока им владеет этот объект. const MergeTreeData::DataPartPtr owned_data_part; /// Кусок не будет удалён, пока им владеет этот объект.
MarkRanges all_mark_ranges; /// В каких диапазонах засечек читать. В порядке возрастания номеров. MarkRanges all_mark_ranges; /// В каких диапазонах засечек читать. В порядке возрастания номеров.
MarkRanges remaining_mark_ranges; /// В каких диапазонах засечек еще не прочли. MarkRanges remaining_mark_ranges; /// В каких диапазонах засечек еще не прочли.
/// В порядке убывания номеров, чтобы можно было выбрасывать из конца. /// В порядке убывания номеров, чтобы можно было выбрасывать из конца.
......
此差异已折叠。
...@@ -7,16 +7,16 @@ ...@@ -7,16 +7,16 @@
#include <DB/Interpreters/sortBlock.h> #include <DB/Interpreters/sortBlock.h>
#include <DB/Storages/StorageMergeTree.h> #include <DB/Storages/MergeTree/MergeTreeData.h>
namespace DB namespace DB
{ {
class MergeTreeBlockOutputStream : public IBlockOutputStream class MergeTreeDataBlockOutputStream : public IBlockOutputStream
{ {
public: public:
MergeTreeBlockOutputStream(StoragePtr owned_storage) : IBlockOutputStream(owned_storage), storage(dynamic_cast<StorageMergeTree &>(*owned_storage)), flags(O_TRUNC | O_CREAT | O_WRONLY) MergeTreeDataBlockOutputStream(MergeTreeData & data, StoragePtr owned_storage) : IBlockOutputStream(owned_storage), storage(data), flags(O_TRUNC | O_CREAT | O_WRONLY)
{ {
} }
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
} }
private: private:
StorageMergeTree & storage; MergeTreeData & storage;
const int flags; const int flags;
...@@ -130,7 +130,7 @@ private: ...@@ -130,7 +130,7 @@ private:
LOG_TRACE(storage.log, "Writing index."); LOG_TRACE(storage.log, "Writing index.");
/// Сначала пишем индекс. Индекс содержит значение PK для каждой index_granularity строки. /// Сначала пишем индекс. Индекс содержит значение PK для каждой index_granularity строки.
StorageMergeTree::DataPart::Index index_vec; MergeTreeData::DataPart::Index index_vec;
index_vec.reserve(part_size * storage.sort_descr.size()); index_vec.reserve(part_size * storage.sort_descr.size());
{ {
...@@ -183,7 +183,7 @@ private: ...@@ -183,7 +183,7 @@ private:
String part_name = storage.getPartName(DayNum_t(min_date), DayNum_t(max_date), part_id, part_id, 0); String part_name = storage.getPartName(DayNum_t(min_date), DayNum_t(max_date), part_id, part_id, 0);
String part_res_path = storage.full_path + part_name + "/"; String part_res_path = storage.full_path + part_name + "/";
StorageMergeTree::DataPartPtr new_data_part = new StorageMergeTree::DataPart(storage); MergeTreeData::DataPartPtr new_data_part = new MergeTreeData::DataPart(storage);
new_data_part->left_date = DayNum_t(min_date); new_data_part->left_date = DayNum_t(min_date);
new_data_part->right_date = DayNum_t(max_date); new_data_part->right_date = DayNum_t(max_date);
new_data_part->left = part_id; new_data_part->left = part_id;
......
#pragma once #pragma once
#include <DB/Storages/StorageMergeTree.h> #include <DB/Storages/MergeTree/MergeTreeData.h>
#include <DB/DataTypes/IDataType.h> #include <DB/DataTypes/IDataType.h>
#include <DB/DataTypes/DataTypeNested.h> #include <DB/DataTypes/DataTypeNested.h>
#include <DB/Core/NamesAndTypes.h> #include <DB/Core/NamesAndTypes.h>
...@@ -22,7 +22,7 @@ class MergeTreeReader ...@@ -22,7 +22,7 @@ class MergeTreeReader
{ {
public: public:
MergeTreeReader(const String & path_, /// Путь к куску MergeTreeReader(const String & path_, /// Путь к куску
const Names & columns_names_, bool use_uncompressed_cache_, StorageMergeTree & storage_) const Names & columns_names_, bool use_uncompressed_cache_, MergeTreeData & storage_)
: path(path_), column_names(columns_names_), use_uncompressed_cache(use_uncompressed_cache_), storage(storage_) : path(path_), column_names(columns_names_), use_uncompressed_cache(use_uncompressed_cache_), storage(storage_)
{ {
for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it) for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it)
...@@ -220,7 +220,7 @@ private: ...@@ -220,7 +220,7 @@ private:
FileStreams streams; FileStreams streams;
Names column_names; Names column_names;
bool use_uncompressed_cache; bool use_uncompressed_cache;
StorageMergeTree & storage; MergeTreeData & storage;
void addStream(const String & name, const IDataType & type, size_t level = 0) void addStream(const String & name, const IDataType & type, size_t level = 0)
{ {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <DB/IO/WriteBufferFromFile.h> #include <DB/IO/WriteBufferFromFile.h>
#include <DB/IO/CompressedWriteBuffer.h> #include <DB/IO/CompressedWriteBuffer.h>
#include <DB/Storages/StorageMergeTree.h> #include <DB/Storages/MergeTree/MergeTreeData.h>
namespace DB namespace DB
...@@ -11,7 +11,7 @@ namespace DB ...@@ -11,7 +11,7 @@ namespace DB
class IMergedBlockOutputStream : public IBlockOutputStream class IMergedBlockOutputStream : public IBlockOutputStream
{ {
public: public:
IMergedBlockOutputStream(StorageMergeTree & storage_) : storage(storage_), index_offset(0) IMergedBlockOutputStream(MergeTreeData & storage_) : storage(storage_), index_offset(0)
{ {
} }
...@@ -182,7 +182,7 @@ protected: ...@@ -182,7 +182,7 @@ protected:
} }
} }
StorageMergeTree & storage; MergeTreeData & storage;
ColumnStreams column_streams; ColumnStreams column_streams;
...@@ -196,7 +196,7 @@ protected: ...@@ -196,7 +196,7 @@ protected:
class MergedBlockOutputStream : public IMergedBlockOutputStream class MergedBlockOutputStream : public IMergedBlockOutputStream
{ {
public: public:
MergedBlockOutputStream(StorageMergeTree & storage_, MergedBlockOutputStream(MergeTreeData & storage_,
UInt16 min_date, UInt16 max_date, UInt64 min_part_id, UInt64 max_part_id, UInt32 level) UInt16 min_date, UInt16 max_date, UInt64 min_part_id, UInt64 max_part_id, UInt32 level)
: IMergedBlockOutputStream(storage_), marks_count(0) : IMergedBlockOutputStream(storage_), marks_count(0)
{ {
...@@ -299,7 +299,7 @@ typedef Poco::SharedPtr<MergedBlockOutputStream> MergedBlockOutputStreamPtr; ...@@ -299,7 +299,7 @@ typedef Poco::SharedPtr<MergedBlockOutputStream> MergedBlockOutputStreamPtr;
class MergedColumnOnlyOutputStream : public IMergedBlockOutputStream class MergedColumnOnlyOutputStream : public IMergedBlockOutputStream
{ {
public: public:
MergedColumnOnlyOutputStream(StorageMergeTree & storage_, String part_path_, bool sync_ = false) : MergedColumnOnlyOutputStream(MergeTreeData & storage_, String part_path_, bool sync_ = false) :
IMergedBlockOutputStream(storage_), part_path(part_path_), initialized(false), sync(sync_) IMergedBlockOutputStream(storage_), part_path(part_path_), initialized(false), sync(sync_)
{ {
} }
......
#pragma once
namespace DB
{
/** Отвечает за хранение локальных данных всех *MergeTree движков.
* - Поддерживает набор кусков на диске. Синхронизирует доступ к ним, поддерживает в памяти их список.
* - Полностью выполняет запросы SELECT.
* - Сам не принимает решений об изменении данных.
* - Умеет двавть рекомендации:
* - Говорить, какие куски нужно удалить, потому что они покрыты другими кусками.
* - Выбирать набор кусков для слияния.
* При этом нужна внешняя информация о том, какие куски с какими разрешено объединять.
* - Умеет изменять данные по запросу:
* - Записать новый кусок с данными из блока.
* - Слить указанные куски.
* - Сделать ALTER.
*/
class MergeTreeData
{
public:
private:
};
}
#include <set>
#include <boost/bind.hpp>
#include <sparsehash/dense_hash_set>
#include <sparsehash/dense_hash_map> #include <sparsehash/dense_hash_map>
#include <sparsehash/dense_hash_set>
#include <DB/Columns/ColumnNested.h> #include <DB/Storages/IColumnsDeclaration.h>
#include <DB/DataTypes/DataTypeNested.h> #include <DB/DataTypes/DataTypeNested.h>
#include <DB/Storages/IStorage.h>
#include <DB/Parsers/ASTIdentifier.h> #include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTNameTypePair.h> #include <DB/Parsers/ASTNameTypePair.h>
#include <DB/Interpreters/Context.h> #include <DB/Interpreters/Context.h>
#include <boost/bind.hpp>
namespace DB namespace DB
{ {
bool IStorage::hasRealColumn(const String &column_name) const bool IColumnsDeclaration::hasRealColumn(const String &column_name) const
{ {
const NamesAndTypesList & real_columns = getColumnsList(); const NamesAndTypesList & real_columns = getColumnsList();
for (auto & it : real_columns) for (auto & it : real_columns)
...@@ -25,7 +20,7 @@ bool IStorage::hasRealColumn(const String &column_name) const ...@@ -25,7 +20,7 @@ bool IStorage::hasRealColumn(const String &column_name) const
} }
NameAndTypePair IStorage::getRealColumn(const String &column_name) const NameAndTypePair IColumnsDeclaration::getRealColumn(const String &column_name) const
{ {
const NamesAndTypesList & real_columns = getColumnsList(); const NamesAndTypesList & real_columns = getColumnsList();
for (auto & it : real_columns) for (auto & it : real_columns)
...@@ -35,19 +30,19 @@ NameAndTypePair IStorage::getRealColumn(const String &column_name) const ...@@ -35,19 +30,19 @@ NameAndTypePair IStorage::getRealColumn(const String &column_name) const
} }
bool IStorage::hasColumn(const String &column_name) const bool IColumnsDeclaration::hasColumn(const String &column_name) const
{ {
return hasRealColumn(column_name); /// По умолчанию считаем, что виртуальных столбцов в сторадже нет. return hasRealColumn(column_name); /// По умолчанию считаем, что виртуальных столбцов в сторадже нет.
} }
NameAndTypePair IStorage::getColumn(const String &column_name) const NameAndTypePair IColumnsDeclaration::getColumn(const String &column_name) const
{ {
return getRealColumn(column_name); /// По умолчанию считаем, что виртуальных столбцов в сторадже нет. return getRealColumn(column_name); /// По умолчанию считаем, что виртуальных столбцов в сторадже нет.
} }
const DataTypePtr IStorage::getDataTypeByName(const String & column_name) const const DataTypePtr IColumnsDeclaration::getDataTypeByName(const String & column_name) const
{ {
const NamesAndTypesList & names_and_types = getColumnsList(); const NamesAndTypesList & names_and_types = getColumnsList();
for (NamesAndTypesList::const_iterator it = names_and_types.begin(); it != names_and_types.end(); ++it) for (NamesAndTypesList::const_iterator it = names_and_types.begin(); it != names_and_types.end(); ++it)
...@@ -58,7 +53,7 @@ const DataTypePtr IStorage::getDataTypeByName(const String & column_name) const ...@@ -58,7 +53,7 @@ const DataTypePtr IStorage::getDataTypeByName(const String & column_name) const
} }
Block IStorage::getSampleBlock() const Block IColumnsDeclaration::getSampleBlock() const
{ {
Block res; Block res;
const NamesAndTypesList & names_and_types = getColumnsList(); const NamesAndTypesList & names_and_types = getColumnsList();
...@@ -104,7 +99,7 @@ static NamesAndTypesMap getColumnsMap(const NamesAndTypesList & available_column ...@@ -104,7 +99,7 @@ static NamesAndTypesMap getColumnsMap(const NamesAndTypesList & available_column
} }
void IStorage::check(const Names & column_names) const void IColumnsDeclaration::check(const Names & column_names) const
{ {
const NamesAndTypesList & available_columns = getColumnsList(); const NamesAndTypesList & available_columns = getColumnsList();
...@@ -134,7 +129,7 @@ void IStorage::check(const Names & column_names) const ...@@ -134,7 +129,7 @@ void IStorage::check(const Names & column_names) const
} }
void IStorage::check(const Block & block, bool need_all) const void IColumnsDeclaration::check(const Block & block, bool need_all) const
{ {
const NamesAndTypesList & available_columns = getColumnsList(); const NamesAndTypesList & available_columns = getColumnsList();
const NamesAndTypesMap & columns_map = getColumnsMap(available_columns); const NamesAndTypesMap & columns_map = getColumnsMap(available_columns);
...@@ -174,7 +169,6 @@ void IStorage::check(const Block & block, bool need_all) const ...@@ -174,7 +169,6 @@ void IStorage::check(const Block & block, bool need_all) const
} }
} }
/// одинаковыми считаются имена, если они совпадают целиком или name_without_dot совпадает с частью имени до точки /// одинаковыми считаются имена, если они совпадают целиком или name_without_dot совпадает с частью имени до точки
static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePair & name_type) static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePair & name_type)
{ {
...@@ -182,7 +176,7 @@ static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePai ...@@ -182,7 +176,7 @@ static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePai
return (name_with_dot == name_type.first.substr(0, name_without_dot.length() + 1) || name_without_dot == name_type.first); return (name_with_dot == name_type.first.substr(0, name_without_dot.length() + 1) || name_without_dot == name_type.first);
} }
void IStorage::alterColumns(const ASTAlterQuery::Parameters & params, NamesAndTypesListPtr & columns, const Context & context) const void IColumnsDeclaration::alterColumns(const ASTAlterQuery::Parameters & params, NamesAndTypesListPtr & columns, const Context & context)
{ {
if (params.type == ASTAlterQuery::ADD) if (params.type == ASTAlterQuery::ADD)
{ {
......
此差异已折叠。
...@@ -192,7 +192,7 @@ StoragePtr StorageFactory::get( ...@@ -192,7 +192,7 @@ StoragePtr StorageFactory::get(
return StorageMergeTree::create( return StorageMergeTree::create(
data_path, table_name, columns, context, primary_expr, date_column_name, sampling_expression, index_granularity, data_path, table_name, columns, context, primary_expr, date_column_name, sampling_expression, index_granularity,
name == "SummingMergeTree" ? StorageMergeTree::Summing : StorageMergeTree::Ordinary); name == "SummingMergeTree" ? MergeTreeData::Summing : MergeTreeData::Ordinary);
} }
else if (name == "CollapsingMergeTree") else if (name == "CollapsingMergeTree")
{ {
...@@ -234,7 +234,7 @@ StoragePtr StorageFactory::get( ...@@ -234,7 +234,7 @@ StoragePtr StorageFactory::get(
return StorageMergeTree::create( return StorageMergeTree::create(
data_path, table_name, columns, context, primary_expr, date_column_name, data_path, table_name, columns, context, primary_expr, date_column_name,
sampling_expression, index_granularity, StorageMergeTree::Collapsing, sign_column_name); sampling_expression, index_granularity, MergeTreeData::Collapsing, sign_column_name);
} }
else if (name == "SystemNumbers") else if (name == "SystemNumbers")
{ {
......
...@@ -37,7 +37,7 @@ DataParts copy(const DataParts &a) ...@@ -37,7 +37,7 @@ DataParts copy(const DataParts &a)
const int RowsPerSec = 100000; const int RowsPerSec = 100000;
StorageMergeTreeSettings settings; MergeTreeSettings settings;
size_t index_granularity = 1; size_t index_granularity = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册