之前相關的文章:
CarbonData 數據管理
本教程將介紹 CarbonData 上的所有命令和數據操作。
- CREATE TABLE
- CREATE EXTERNAL TABLE
- CREATE DATABASE
- TABLE MANAGEMENT
- LOAD DATA
- UPDATE AND DELETE
- COMPACTION
- PARTITION
- BUCKETING
- SEGMENT MANAGEMENT
CREATE TABLE
這個命令可用於通過指定字段列表以及表格屬性來創建 CarbonData 表,您還可以指定表存儲的位置。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name[(col_name data_type , ...)]
STORED BY 'carbondata'
[TBLPROPERTIES (property_name=property_value, ...)]
[LOCATION 'path']
注意: CarbonData 同時支持 "STORED AS carbondata" 和 "USING carbondata",請訪問 CarbonData 庫中的示例代碼 CarbonSessionExample 。
使用指南
以下是 TBLPROPERTIES 的使用原則,CarbonData 的附加表選項可以通過 carbon.properties 設置。
- 字典編碼配置
- 從 1.3 開始,字典編碼默認對所有的列關閉,你可以使用此命令來包含或排除列以進行字典編碼。建議使用用例:對低基數(low cardinality)列進行字典編碼,可能有助於提高數據壓縮率和性能。
- TBLPROPERTIES ('DICTIONARY_INCLUDE'='column1, column2')
- 倒排索引配置
- 默認情況下,倒排索引是啟用的, 這可能有助於提高壓縮率和查詢速度,特別是對除於有利位置的低基數列。建議使用用例:對於高基數(high cardinality)列,你可以禁用倒排索引以提高數據加載性能。
- TBLPROPERTIES ('NO_INVERTED_INDEX'='column1, column3')
- 排序列的配置
- 這個屬性供用戶指定哪些列屬於MDK(Multi-Dimensions-Key)索引。
- 如果用戶沒有指定 "SORT_COLUMN" 屬性, 默認情況下,除了複雜類型的列其他類型的列都會創建 MDK 索引。
- 如果指定了這個屬性,但是沒有指定參數,這樣表在加載的時候不會被排序
- 這個屬性只支持 string, date, timestamp, short, int, long 以及 boolean 數據類型。建議使用用例: 只為需要的列建立 MDK 索引,這可能有助於提高數據加載性能。
- TBLPROPERTIES ('SORT_COLUMNS'='column1, column3')
- OR
- TBLPROPERTIES ('SORT_COLUMNS'='')
- 排序範圍配置
- 這個屬性供用戶在數據加載期間指定排序範圍,以下是排序範圍的類型。
- LOCAL_SORT: 這是默認的排序範圍
- NO_SORT: 這將會以未經排序的方式加載數據,會顯著提高負載性能。
- BATCH_SORT: 如果塊個數 > 並行性,它將增加數據的加載性能,但會減少數據的查詢性能。
- GLOBAL_SORT: 這會增加數據的查詢性能,特別是高併發查詢。如果你特別關心加載資源的隔離時使用,因為系統使用 Spark 的 GroupBy 對數據進行排序,我們可以通過 Spark 來控制資源。
- 表塊大小配置
- 這個屬性用於設置表的塊大小,默認值是 1024 MB,這個屬性只能設置在 1MB ~ 2048MB 之間。
- TBLPROPERTIES ('TABLE_BLOCKSIZE'='512')
- 注意: 512 或者 512M 兩種寫法都支持。
- 表壓縮(Compaction)配置
- 這個屬性是表級別的壓縮配置,如果沒有指定,carbon.properties 文件中系統級別的配置將會被使用。以下是5種配置:
- MAJOR_COMPACTION_SIZE: 和 carbon.major.compaction.size 參數的意思一致,單位是 MB。
- AUTO_LOAD_MERGE: 和 carbon.enable.auto.load.merge 參數的意思一致。
- COMPACTION_LEVEL_THRESHOLD: 和 carbon.compaction.level.threshold 參數的意思一致。
- COMPACTION_PRESERVE_SEGMENTS: 和 carbon.numberof.preserve.segments 參數的意思一致。
- ALLOWED_COMPACTION_DAYS: 和 carbon.allowed.compaction.days 參數的意思一致。
- TBLPROPERTIES ('MAJOR_COMPACTION_SIZE'='2048',
- 'AUTO_LOAD_MERGE'='true',
- 'COMPACTION_LEVEL_THRESHOLD'='5,6',
- 'COMPACTION_PRESERVE_SEGMENTS'='10',
- 'ALLOWED_COMPACTION_DAYS'='5')
- Streaming
- CarbonData 支持流式攝取實時數據。您可以使用以下表屬性創建 streaming 表。
- TBLPROPERTIES ('streaming'='true')
示例:
CREATE TABLE IF NOT EXISTS productSchema.productSalesTable (
productNumber INT,
productName STRING,
storeCity STRING,
storeProvince STRING,
productCategory STRING,
productBatch STRING,
saleQuantity INT,
revenue INT)
STORED BY 'carbondata'
TBLPROPERTIES ('SORT_COLUMNS'='productName,storeCity',
'SORT_SCOPE'='NO_SORT')
注意: CarbonData 同時支持 "STORED AS carbondata" 和 "USING carbondata",請訪問 CarbonData 庫中的示例代碼 CarbonSessionExample 。
CREATE TABLE AS SELECT
這個功能允許用戶從任何 Parquet/Hive/Carbon表來創建 Carbon 表。當用戶想要從任何其他 Parquet/Hive 表創建 Carbon 表,然後使用 Carbon 查詢引擎查詢並獲得更好的查詢結果時更有用。當然,這種方式也可用於備份數據。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
STORED BY 'carbondata'
[TBLPROPERTIES (key1=val1, key2=val2, ...)]
AS select_statement;
示例
carbon.sql("CREATE TABLE source_table(
id INT,
name STRING,
city STRING,
age INT)
STORED AS parquet")
carbon.sql("INSERT INTO source_table SELECT 1,'bob','shenzhen',27")
carbon.sql("INSERT INTO source_table SELECT 2,'david','shenzhen',31")
carbon.sql("CREATE TABLE target_table
STORED BY 'carbondata'
AS SELECT city,avg(age) FROM source_table GROUP BY city")
carbon.sql("SELECT * FROM target_table").show
// results:
// +--------+--------+
// | city|avg(age)|
// +--------+--------+
// |shenzhen| 29.0|
// +--------+--------+
CREATE EXTERNAL TABLE
該功能允許用戶通過指定位置來創建外部表。
CREATE EXTERNAL TABLE [IF NOT EXISTS] [db_name.]table_name
STORED BY 'carbondata' LOCATION ?$FilesPath?
在託管表(managed table)數據位置上創建外部表。
託管表數據位置將包含 FACT 和 Metadata 文件夾。 這些數據可以通過創建一個普通的 carbon 表來生成,並使用這個路徑作為上面語法中 $FilesPath 的值。
示例:
sql("CREATE TABLE origin(key INT, value STRING) STORED BY 'carbondata'")
sql("INSERT INTO origin select 100,'spark'")
sql("INSERT INTO origin select 200,'hive'")
// creates a table in $storeLocation/origin
sql(s"""
|CREATE EXTERNAL TABLE source
|STORED BY 'carbondata'
|LOCATION '$storeLocation/origin'
""".stripMargin)
checkAnswer(sql("SELECT count(*) from source"), sql("SELECT count(*) from origin"))
在非事務(Non-Transactional)表數據位置上創建外部表。
非事務(Non-Transactional)表的數據位置裡面僅僅包含 carbondata 和 carbonindex 文件,裡面不會有 metadata 文件夾(表狀態和模式)。 我們的 SDK 模塊目前僅支持以這種格式寫入數據。
示例:
sql(
s"""CREATE EXTERNAL TABLE sdkOutputTable STORED BY 'carbondata' LOCATION
|'$writerPath' """.stripMargin)
這裡的 $writerPath 文件夾裡面只會有 carbondata 和索引文件。 可能是 SDK 的輸出文件。請參見 SDK 寫入指南。
注意: 刪除外部表不會刪除路徑下的文件。
CREATE DATABASE
這個功能用於創建一個新的數據庫。默認情況下,數據庫是在 Carbon 的 store location 創建的,但你也可以指定自定義位置。
CREATE DATABASE [IF NOT EXISTS] database_name [LOCATION path];
示例
CREATE DATABASE carbon LOCATION ?hdfs://name_cluster/dir1/carbonstore?;
TABLE MANAGEMENT
SHOW TABLE
這個命令可用於列出當前數據庫中的所有表或著特定數據庫中的所有表。
SHOW TABLES [IN db_Name]
示例:
SHOW TABLES
OR
SHOW TABLES IN defaultdb
ALTER TABLE
以下章節介紹用於修改現有表的物理或邏輯狀態的命令。
- RENAME TABLE
- 這個命令用於重命名當前表
- ALTER TABLE [db_name.]table_name RENAME TO new_table_name
- 示例:
- ALTER TABLE carbon RENAME TO carbonTable
- OR
- ALTER TABLE test_db.carbon RENAME TO test_db.carbonTable
- ADD COLUMNS
- 這個命令用於在已存在的表中添加新的列。
- ALTER TABLE [db_name.]table_name ADD COLUMNS (col_name data_type,...)
- TBLPROPERTIES('DICTIONARY_INCLUDE'='col_name,...',
- 'DEFAULT.VALUE.COLUMN_NAME'='default_value')
- 示例:
- ALTER TABLE carbon ADD COLUMNS (a1 INT, b1 STRING)
- ALTER TABLE carbon ADD COLUMNS (a1 INT, b1 STRING) TBLPROPERTIES('DICTIONARY_INCLUDE'='a1')
- ALTER TABLE carbon ADD COLUMNS (a1 INT, b1 STRING) TBLPROPERTIES('DEFAULT.VALUE.a1'='10')
- DROP COLUMNS
- 這個命令可以刪除給定表中的列
- ALTER TABLE [db_name.]table_name DROP COLUMNS (col_name, ...)
- 示例:
- ALTER TABLE carbon DROP COLUMNS (b1)
- OR
- ALTER TABLE test_db.carbon DROP COLUMNS (b1)
- ALTER TABLE carbon DROP COLUMNS (c1,d1)
- CHANGE DATA TYPE
- 這個命令用於將數據類型從 INT 更改為 BIGINT 或將 decimal 從低精度更改為更高的精度。僅在沒有數據丟失的情況下才支持將 decimal 數據類型從較低精度更改為較高精度。
- ALTER TABLE [db_name.]table_name CHANGE col_name col_name changed_column_type
- 有效方案
- 無效的場景 - 將 decimal 的精度從(10,2)轉換成(10,5)是無效的,因為在這種情況下,只有比例(譯者注 2變成5)增加,但總位數保持不變。
- 有效的場景 - 將 decimal 的精度從(10,2)轉換成(12,3)是有效的,因為總的位數增加了2(譯者注 10變成12),比例只增加 1,這種情況不會出現數據丟數。
- 注意: 允許的範圍是 38,38(精度,範圍),並且是一種有效的大寫(upper case)情況,不會導致數據丟失。
- 示例1:將 a1 的數據類型從 INT 轉換成 BIGINT。
- ALTER TABLE test_db.carbon CHANGE a1 a1 BIGINT
- 示例2:將 a1 的 decimal 精度從 10 轉換成 18。
- ALTER TABLE test_db.carbon CHANGE a1 a1 DECIMAL(18,2)
DROP TABLE
這個命令用於刪除已存在的表
DROP TABLE [IF EXISTS] [db_name.]table_name
示例:
DROP TABLE IF EXISTS productSchema.productSalesTable
REFRESH TABLE
該命令用於從現有 Carbon 表數據將 Carbon 表註冊到 HIVE 元存儲目錄。
REFRESH TABLE $db_NAME.$table_NAME
示例:
REFRESH TABLE dbcarbon.productSalesTable
注意:
- 新的數據庫名字必須和老的數據庫名字一致。
- 在執行此命令之前,應將舊錶的模式和數據複製到新數據庫相應的位置。
- 如果表是聚合表,所有的聚合表需要複製到新的數據庫中。
- 對於舊存儲(old store),源和目標群集的時區應該相同。
- 如果舊集群使用 HIVE 元存儲來存儲模式,則刷新將不起作用,因為模式文件沒有存儲在文件系統中。
表和列註釋
你可以通過表註釋來提供更多的信息。同樣,你也可以使用列註釋提供某列的更多信息。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
STORED BY 'carbondata'
[TBLPROPERTIES (property_name=property_value, ...)]
示例:
CREATE TABLE IF NOT EXISTS productSchema.productSalesTable (
productNumber Int COMMENT 'unique serial number for product')
COMMENT ?This is table comment?
STORED BY 'carbondata'
TBLPROPERTIES ('DICTIONARY_INCLUDE'='productNumber')
你也可以使用 ALTER 命令來 SET 和 UNSET 表的註釋。
SET 表註釋的例子:
ALTER TABLE carbon SET TBLPROPERTIES ('comment'='this table comment is modified');
UNSET 表註釋的例子:
ALTER TABLE carbon UNSET TBLPROPERTIES ('comment');
LOAD DATA
將數據加載到 CARBONDATA 表中
這個命令用於加載 csv 格式的文件到 carbondata 表中, OPTIONS 參數在加載數據的過程中是可選的。在 OPTIONS 中我們可以指定任何的先決條件,比如:DELIMITER, QUOTECHAR, FILEHEADER, ESCAPECHAR, MULTILINE。
LOAD DATA [LOCAL] INPATH 'folder_path'
INTO TABLE [db_name.]table_name
OPTIONS(property_name=property_value, ...)
你可以使用下面的選項來加載數據:
- DELIMITER: 加載命令中可以指定數據的分隔符。
- OPTIONS('DELIMITER'=',')
- QUOTECHAR: 加載命令中可以指定數據的引用字符。
- OPTIONS('QUOTECHAR'='"')
- COMMENTCHAR: 可以在加載命令中提供註釋標識符,用於註釋掉你不需要的數據。
- OPTIONS('COMMENTCHAR'='#')
- HEADER: 如果你加載不帶文件頭的 CSV 文件並且文件頭和表的模式一致,這時候你可以在加載數據的 SQL 裡面加上 'HEADER'='false',這時候用戶就不需要指定文件頭。默認情況下這個屬性的值是 'true'。 false: CSV 文件不帶文件頭;true: CSV 文件帶文件頭。
- OPTIONS('HEADER'='false')
- 注意: 如果 HEADER 選項存在,並且其值為 'true',這時候 FILEHEADER 選項就可選了。
- FILEHEADER: 如果源文件裡面不存在頭信息,那麼可以通過這個選項在 LOAD DATA 命令提供 Headers 。
- OPTIONS('FILEHEADER'='column1,column2')
- MULTILINE: CSV 引號中帶有換行符。
- OPTIONS('MULTILINE'='true')
- ESCAPECHAR: 如果用戶希望嚴格驗證 CSV 文件中的轉義字符,可以提供轉義字符。
- OPTIONS('ESCAPECHAR'='\')
- SKIP_EMPTY_LINE: 在數據加載過程中忽略 CSV 文件中的空行。
- OPTIONS('SKIP_EMPTY_LINE'='TRUE/FALSE')
- COMPLEX_DELIMITER_LEVEL_1: 分割一行中的複雜類型的數據列 (eg., a$b$c --> Array = {a,b,c}).
- OPTIONS('COMPLEX_DELIMITER_LEVEL_1'='$')
- COMPLEX_DELIMITER_LEVEL_2: 分割一行中嵌套的複雜類型數據列. 根據複雜數據類型,提供 level_1 & level_2 分隔符(eg., a:b$c:d --> Array> = {{a,b},{c,d}}).
- OPTIONS('COMPLEX_DELIMITER_LEVEL_2'=':')
- ALL_DICTIONARY_PATH: 所有字典文件的路徑。
- OPTIONS('ALL_DICTIONARY_PATH'='/opt/alldictionary/data.dictionary')
- COLUMNDICT: 指定列的字典文件路徑.
- OPTIONS('COLUMNDICT'='column1:dictionaryFilePath1,column2:dictionaryFilePath2')
- 注意: ALL_DICTIONARY_PATH 和 COLUMNDICT 不能同時使用。
- DATEFORMAT/TIMESTAMPFORMAT: 指定列的日期和時間戳格式。
- OPTIONS('DATEFORMAT' = 'yyyy-MM-dd','TIMESTAMPFORMAT'='yyyy-MM-dd HH:mm:ss')
- 注意: 日期格式由日期模式字符串指定。 Carbondata 中的日期模式字符串和 JAVA 中的一致,請參見SimpleDateFormat.
- SORT COLUMN BOUNDS: 排序列的範圍界限。
- 假設表是用 'SORT_COLUMNS'='name,id' 創建的,並且 name 的範圍是aaa ~ zzz,id 的值範圍是0 ~ 1000。那麼在數據加載的時候,我們可以通過指定下面的選項來加強數據加載的性能。
- OPTIONS('SORT_COLUMN_BOUNDS'='f,250;l,500;r,750')
- 每個範圍使用 ';' 分割,範圍裡面每個字段值使用 ','。在上面的例子中,我們提供了 3 個邊界來將記錄分佈到 4 個分區。 'f','l','r' 邊界值可以平均分配(evenly distribute)記錄。在 carbondata 內部,為了記錄,我們比較排序列的值和邊界的值,並決定記錄將被轉發到哪個分區。
- 注意:
- 僅在 SORT_SCOPE 的值為 'local_sort' 的時候,SORT_COLUMN_BOUNDS 才會被使用。
- Carbondata 將在最終的排序過程中使用這些邊界作為範圍來同時處理數據。記錄將在每個分區內排序並寫出。由於分區已排序,所有記錄將被排序。
- 由於字典列的實際順序和字面順序不一定相同,因此如果第一個排序列是'dictionary_include',我們不建議您使用此功能。
- 如果您在加載數據期間 CPU 的使用率較低,該選項可以更好地工作。如果您的系統已經處於緊張狀態,最好不要使用此選項。此外,性能還取決於用戶指定的邊界。如果用戶不知道使數據在邊界之間均勻分佈的確切邊界,加載性能仍然會比以前好或至少與以前相同。
- 用戶可以在 PR1953 的描述中找到有關該選項的更多信息。
- SINGLE_PASS: Single Pass 加載可以使用單個作業即時完成數據加載以及字典生成。它增強了在初始加載數據之後的涉及字典上很少增量更新的後續數據加載場景下的性能。
該選項指定是否使用單通道加載數據。 默認情況下,該選項設置為 FALSE。
OPTIONS('SINGLE_PASS'='TRUE')
注意:
- 如果此選項設置為 TRUE,則數據加載將花費較少的時間。
- 如果此選項設置為除 TRUE 或 FALSE 之外的某個無效值,則會使用默認值。
示例:
LOAD DATA local inpath '/opt/rawdata/data.csv' INTO table carbontable
options('DELIMITER'=',', 'QUOTECHAR'='"','COMMENTCHAR'='#',
'HEADER'='false',
'FILEHEADER'='empno,empname,designation,doj,workgroupcategory,
workgroupcategoryname,deptno,deptname,projectcode,
projectjoindate,projectenddate,attendance,utilization,salary',
'MULTILINE'='true','ESCAPECHAR'='\','COMPLEX_DELIMITER_LEVEL_1'='$',
'COMPLEX_DELIMITER_LEVEL_2'=':',
'ALL_DICTIONARY_PATH'='/opt/alldictionary/data.dictionary',
'SINGLE_PASS'='TRUE')
- BAD RECORDS HANDLING: 處理壞記錄(bad records)的方法如下:
- 在處理錯誤之前加載所有數據。
- 在加載數據前清理或刪除壞記錄,或在發現壞記錄時停止數據加載。
- OPTIONS('BAD_RECORDS_LOGGER_ENABLE'='true', 'BAD_RECORD_PATH'='hdfs://hacluster/tmp/carbon', 'BAD_RECORDS_ACTION'='REDIRECT', 'IS_EMPTY_DATA_BAD_RECORD'='false')
注意:
- 對於壞記錄,BAD_RECORDS_ACTION 屬性主要有四種操作類型:FORCE, REDIRECT, IGNORE 和 FAIL。
- FAIL 是其默認的值。如果使用 FAIL 選項,則如果發現任何壞記錄,數據加載將會失敗。
- 如果使用了 REDIRECT 選項, CarbonData 會將所有壞記錄添加到單獨的 CSV 文件中。 但是,在後續的數據加載我們不能使用這個文件,因為其內容可能與原始記錄不完全匹配。建議你事先對原始源數據進行清理,以進行下一步的數據處理。此選項主要用於提醒你哪些記錄是壞記錄
- 如果使用了 FORCE 選項,那麼會在加載數據之前將壞記錄存儲為 NULL,然後再存儲。
- 如果使用了 IGNORE 選項,那麼壞記錄不會被加載,也不會寫到單獨的 CSV 文件中。
- 在加載的數據中,如果所有記錄都是壞記錄,則 BAD_RECORDS_ACTION 選項將會無效,加載操作會失敗。
- 每列的最大字符數為 32000,如果列中的字符數超過 32000 個,則數據加載將會失敗。
示例:
LOAD DATA INPATH 'filepath.csv' INTO TABLE tablename
OPTIONS('BAD_RECORDS_LOGGER_ENABLE'='true','BAD_RECORD_PATH'='hdfs://hacluster/tmp/carbon',
'BAD_RECORDS_ACTION'='REDIRECT','IS_EMPTY_DATA_BAD_RECORD'='false')
將數據插入到 CARBONDATA 表中
這個命令可以將數據插入到 CarbonData 中,它被分別定義為 Insert 和 Select 查詢的組合。它將源表中的記錄插入到 CarbonData 表中,源表可以是一個 Hive 表、Parquet 表 或者是 CarbonData 表。它具有通過在源表上執行 Select 查詢來聚合表的記錄並將其處理的結果加載到 CarbonData 表中的功能。
INSERT INTO TABLE
[ WHERE {
你可以忽略掉 table 關鍵字,並按照下面的格式編寫你的查詢:
INSERT INTO
[ WHERE {
覆蓋插入數據:
INSERT OVERWRITE TABLE
[ WHERE {
注意 :
- 源表和 CarbonData 表必須具有相同的表模式。
- 源表和目標表列的數據類型必須相同
- 如果發現壞記錄,INSERT INTO 命令不支持部分成功,這種情況下它會直接失敗。
- 在數據從源表插入到目標表的過程中,源表不能進行插入或更新操作。
示例
INSERT INTO table1 SELECT item1, sum(item2 + 1000) as result FROM table2 group by item1
INSERT INTO table1 SELECT item1, item2, item3 FROM table2 where item2='xyz'
INSERT OVERWRITE TABLE table1 SELECT * FROM TABLE2
UPDATE AND DELETE
UPDATE
這個命令允許根據列表達式和可選的過濾條件更新來 CarbonData 表。
UPDATE
SET (column_name1, column_name2, ... column_name n) = (column1_expression , column2_expression, ... column n_expression )
[ WHERE {
或者,下面的命令也可以用於更新 CarbonData 表:
UPDATE
SET (column_name1, column_name2) =(select sourceColumn1, sourceColumn2 from sourceTable [ WHERE {
[ WHERE {
注意:如果源表中的多個輸入行與目標表中的單行匹配,update 命令將會失敗。
示例:
UPDATE t3 SET (t3_salary) = (t3_salary + 9) WHERE t3_name = 'aaa1'
UPDATE t3 SET (t3_date, t3_country) = ('2017-11-18', 'india') WHERE t3_salary < 15003
UPDATE t3 SET (t3_country, t3_name) = (SELECT t5_country, t5_name FROM t5 WHERE t5_id = 5) WHERE t3_id < 5
UPDATE t3 SET (t3_date, t3_serialname, t3_salary) = (SELECT '2099-09-09', t5_serialname, '9999' FROM t5 WHERE t5_id = 5) WHERE t3_id < 5
UPDATE t3 SET (t3_country, t3_salary) = (SELECT t5_country, t5_salary FROM t5 FULL JOIN t3 u WHERE u.t3_id = t5_id and t5_id=6) WHERE t3_id >6
DELETE
這個命令允許我們從 CarbonData 表中刪除記錄。
DELETE FROM table_name [WHERE expression]
示例:
DELETE FROM carbontable WHERE column1 = 'china'
DELETE FROM carbontable WHERE column1 IN ('china', 'USA')
DELETE FROM carbontable WHERE column1 IN (SELECT column11 FROM sourceTable2)
DELETE FROM carbontable WHERE column1 IN (SELECT column11 FROM sourceTable2 WHERE column1 = 'USA')
COMPACTION
壓縮可以顯著地提高查詢性能。
有幾種類型的 Compaction。
ALTER TABLE [db_name.]table_name COMPACT 'MINOR/MAJOR/CUSTOM'
- Minor Compaction
在 Minor compaction 中,用戶可以指定要合併的文件數量。如果 carbon.enable.auto.load.merge 參數設置為 true,則 Minor compaction 會在每次數據加載的時候觸發。如果有 segments 可以合併,則 minor compaction 將與數據加載並行運行,minor compaction 有兩個級別:
- Level 1: 合併尚未壓縮的 segments。
- Level 2: 合併已經壓縮(Level 1)的 segments 以形成更大的 segment。
ALTER TABLE table_name COMPACT 'MINOR'
- Major Compaction
在 Major compaction 中,多個 segments 可以合併成一個大的 segment。用戶需要指定壓縮的大小以便可以合併 segments,Major compaction 通常在非高峰時段完成。可以選擇一個適當的值來配置 carbon.major.compaction.size 屬性,這個屬性的單位是 MB。
下面命令將指定數量的 segments 合併到一個 segment 中:
ALTER TABLE table_name COMPACT 'MAJOR'
- Custom Compaction
在自定義壓縮中,用戶可以直接指定要合併到一個大片段中的 segment ID。 所有指定的分段 ID 都應存在且有效,否則壓縮將失敗。 自定義壓縮通常在非高峰期進行。
ALTER TABLE table_name COMPACT 'CUSTOM' WHERE SEGMENT.ID IN (2,3,4)
- 在壓縮完成之後清理 segments
清理已經壓縮的 segments:
CLEAN FILES FOR TABLE carbon_table
PARTITION
STANDARD PARTITION
Carbondata 的分區與 Spark 和 Hive 的分區是類似的, 用戶可以使用任何的列來建立分區:
創建分區表
下面命令允許你創建帶有分區的表。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type , ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type , ...)]
[STORED BY file_format]
[TBLPROPERTIES (property_name=property_value, ...)]
示例:
CREATE TABLE IF NOT EXISTS productSchema.productSalesTable (
productNumber INT,
productName STRING,
storeCity STRING,
storeProvince STRING,
saleQuantity INT,
revenue INT)
PARTITIONED BY (productCategory STRING, productBatch STRING)
STORED BY 'carbondata'
使用靜態分區加載數據
下面命令允許你使用靜態分區來加載數據。
LOAD DATA [LOCAL] INPATH 'folder_path'
INTO TABLE [db_name.]table_name PARTITION (partition_spec)
OPTIONS(property_name=property_value, ...)
INSERT INTO INTO TABLE [db_name.]table_name PARTITION (partition_spec)
示例:
LOAD DATA LOCAL INPATH '${env:HOME}/staticinput.csv'
INTO TABLE locationTable
PARTITION (country = 'US', state = 'CA')
INSERT INTO TABLE locationTable
PARTITION (country = 'US', state = 'AL')
SELECT
使用動態分區加載數據
下面命令允許你使用動態分區來加載數據。如果未指定分區,則該分區被視為動態分區。
示例:
LOAD DATA LOCAL INPATH '${env:HOME}/staticinput.csv'
INTO TABLE locationTable
INSERT INTO TABLE locationTable
SELECT
列出所有分區
這個命令獲取表的 Hive 分區信息。
SHOW PARTITIONS [db_name.]table_name
刪除分區
這個命令僅刪除指定的 Hive 分區。
ALTER TABLE table_name DROP [IF EXISTS] PARTITION (part_spec, ...)
示例:
ALTER TABLE locationTable DROP PARTITION (country = 'US');
Insert OVERWRITE
這個命令允許你在特定分區上插入或加載數據,並覆蓋原有數據。
INSERT OVERWRITE TABLE table_name
PARTITION (column = 'partition_name')
select_statement
示例:
INSERT OVERWRITE TABLE partitioned_user
PARTITION (country = 'US')
SELECT * FROM another_user au
WHERE au.country = 'US';
CARBONDATA PARTITION(HASH,RANGE,LIST) -- Alpha 功能,此分區功能不支持更新和刪除數據。
這個分區支持三種類型:(Hash,Range,List), 類似於其他系統的分區功能,CarbonData 的分區功能可用於通過對分區列進行過濾來提高查詢性能。
創建哈希分區表
下面命令允許你創建一個哈希分區表。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type , ...)]
PARTITIONED BY (partition_col_name data_type)
STORED BY 'carbondata'
[TBLPROPERTIES ('PARTITION_TYPE'='HASH',
'NUM_PARTITIONS'='N' ...)]
注意: N 是哈希分區的個數
示例:
CREATE TABLE IF NOT EXISTS hash_partition_table(
col_A STRING,
col_B INT,
col_C LONG,
col_D DECIMAL(10,2),
col_F TIMESTAMP
) PARTITIONED BY (col_E LONG)
STORED BY 'carbondata' TBLPROPERTIES('PARTITION_TYPE'='HASH','NUM_PARTITIONS'='9')
創建範圍分區表
下面命令允許你創建一個範圍分區表。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type , ...)]
PARTITIONED BY (partition_col_name data_type)
STORED BY 'carbondata'
[TBLPROPERTIES ('PARTITION_TYPE'='RANGE',
'RANGE_INFO'='2014-01-01, 2015-01-01, 2016-01-01, ...')]
注意:
- 'RANGE_INFO' 必須在表屬性中按升序定義。
- 日期/時間戳類型的分區列默認格式為yyyy-MM-dd。 我們可以在 CarbonProperties 裡面自定義日期/時間戳格式。
示例:
CREATE TABLE IF NOT EXISTS range_partition_table(
col_A STRING,
col_B INT,
col_C LONG,
col_D DECIMAL(10,2),
col_E LONG
) partitioned by (col_F Timestamp)
PARTITIONED BY 'carbondata'
TBLPROPERTIES('PARTITION_TYPE'='RANGE',
'RANGE_INFO'='2015-01-01, 2016-01-01, 2017-01-01, 2017-02-01')
創建列表分區表
下面命令允許你創建一個列表分區表。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type , ...)]
PARTITIONED BY (partition_col_name data_type)
STORED BY 'carbondata'
[TBLPROPERTIES ('PARTITION_TYPE'='LIST',
'LIST_INFO'='A, B, C, ...')]
注意 : 列表分區支持一個組級別的列表信息。
示例:
CREATE TABLE IF NOT EXISTS list_partition_table(
col_B INT,
col_C LONG,
col_D DECIMAL(10,2),
col_E LONG,
col_F TIMESTAMP
) PARTITIONED BY (col_A STRING)
STORED BY 'carbondata'
TBLPROPERTIES('PARTITION_TYPE'='LIST',
'LIST_INFO'='aaaa, bbbb, (cccc, dddd), eeee')
列出所有分區
執行以下命令可以獲取表的分區信息
SHOW PARTITIONS [db_name.]table_name
添加分區
ALTER TABLE [db_name].table_name ADD PARTITION('new_partition')
分區拆分
ALTER TABLE [db_name].table_name SPLIT PARTITION(partition_id) INTO('new_partition1', 'new_partition2'...)
刪除分區
只刪除分區定義,但保留數據
ALTER TABLE [db_name].table_name DROP PARTITION(partition_id)
同時刪除分區定義和數據
ALTER TABLE [db_name].table_name DROP PARTITION(partition_id) WITH DATA
注意:
- 哈希分區表不支持 ADD, SPLIT 和 DROP 命令
- Partition Id:在 CarbonData 中,分區的劃分並不是使用文件夾實現的,而是使用分區 ID。可以利用這個特性,並減少一些元數據。
SegmentDir/0_batchno0-0-1502703086921.carbonindex
^
SegmentDir/part-0-0_batchno0-0-1502703086921.carbondata
^
以下是提高 carbonData 分區表查詢性能的一些使用技巧:
- 分區列可以從 SORT_COLUMNS 中排除,這將使其他列可以進行一些高效的排序。
- 如果你使用的表是分區表,請嘗試分區列上添加一些過濾條件。
BUCKETING
Bucket 功能可將表/分區的數據分發/組織成多個文件,使得相似的記錄在同一個文件中顯示。在創建表時,用戶需要指定用於分桶的列以及桶的數量。對於桶的選擇,使用列的哈希值。
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type, ...)]
STORED BY 'carbondata'
TBLPROPERTIES('BUCKETNUMBER'='noOfBuckets',
'BUCKETCOLUMNS'='columnname')
注意:
- 複雜數據類型的列不能作為分桶的字段
- BUCKETCOLUMN 參數中的列必須是維度(dimensions).BUCKETCOLUMN 參數不能是度量(measure)或度量和維度的組合。
示例:
CREATE TABLE IF NOT EXISTS productSchema.productSalesTable (
productNumber INT,
saleQuantity INT,
productName STRING,
storeCity STRING,
storeProvince STRING,
productCategory STRING,
productBatch STRING,
revenue INT)
STORED BY 'carbondata'
TBLPROPERTIES ('BUCKETNUMBER'='4', 'BUCKETCOLUMNS'='productName')
SEGMENT MANAGEMENT
SHOW SEGMENT
這個命令用於列出 CarbonData 表的段(segments)。
SHOW [HISTORY] SEGMENTS FOR TABLE [db_name.]table_name LIMIT number_of_segments
示例: 顯示可見的 segments
SHOW SEGMENTS FOR TABLE CarbonDatabase.CarbonTable LIMIT 4
顯示所有的 segments, 包括不可見的 segments
SHOW HISTORY SEGMENTS FOR TABLE CarbonDatabase.CarbonTable LIMIT 4
DELETE SEGMENT BY ID
這個命令可以根據 segment ID 來刪除 segment。每個 segment 都有一個 segment ID 與其關聯。使用這個 segment ID 你就可以刪除這個 segment 了。
下面命令可以獲取 segment ID.
SHOW SEGMENTS FOR TABLE [db_name.]table_name LIMIT number_of_segments
在你檢索到要刪除的 segment 的 segment ID後,執行以下命令刪除選定的 segment。
DELETE FROM TABLE [db_name.]table_name WHERE SEGMENT.ID IN (segment_id1, segments_id2, ...)
示例:
DELETE FROM TABLE CarbonDatabase.CarbonTable WHERE SEGMENT.ID IN (0)
DELETE FROM TABLE CarbonDatabase.CarbonTable WHERE SEGMENT.ID IN (0,5,8)
DELETE SEGMENT BY DATE
該命令根據用戶在 DML 命令中提供的日期從存儲中刪除 CarbonData segment(s)。在特定日期之前創建的 segment 將從存儲中刪除。
DELETE FROM TABLE [db_name.]table_name WHERE SEGMENT.STARTTIME BEFORE DATE_VALUE
示例:
DELETE FROM TABLE CarbonDatabase.CarbonTable WHERE SEGMENT.STARTTIME BEFORE '2017-06-01 12:05:06'
QUERY DATA WITH SPECIFIED SEGMENTS
該命令用於在 CarbonScan 期間從指定的 segments 中讀取數據。
獲取 Segment ID:
SHOW SEGMENTS FOR TABLE [db_name.]table_name LIMIT number_of_segments
給表設置 segment IDs
SET carbon.input.segments.
注意: carbon.input.segments: 指定需要查詢的 segment IDs。這個命令允許你為表指定需要查詢的 segments。這時候 CarbonScan 只會從指定的 segments 讀取數據。
如果用戶想以多線程模式讀取 segments,則使用 CarbonSession。 threadSet 可以用來代替 SET 查詢。
CarbonSession.threadSet ("carbon.input.segments.");
重置 segment IDs
SET carbon.input.segments.
如果用戶想以多線程模式讀取 segments,則使用 CarbonSession。 threadSet 可以用來代替 SET 查詢。
CarbonSession.threadSet ("carbon.input.segments.
示例:
- 下面例子顯示 segment ID 列表,segment 狀態和其他詳細信息,然後指定要讀取的 segment 列表。
SHOW SEGMENTS FOR carbontable1;
SET carbon.input.segments.db.carbontable1 = 1,3,9;
- 以多線程模式查詢 segments 的示例:
CarbonSession.threadSet ("carbon.input.segments.db.carbontable_Multi_Thread","1,3");
- 多線程環境中的線程集示例(以下顯示瞭如何在 Scala 代碼中使用):
def main(args: Array[String]) {
Future {
CarbonSession.threadSet ("carbon.input.segments.db.carbontable_Multi_Thread","1")
spark.sql("select count(empno) from carbon.input.segments.db.carbontable_Multi_Thread").show();
}
}
閱讀更多 從大數據說起 的文章