日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

列存索引

索引是加速數據查詢的重要方法。列存索引可以增強寬表中海量數據的分析計算能力,主要適用于車聯網與物聯網的設備信息統計、電商領域的數據分析、物流行業的訂單統計等場景。本文介紹列存索引的基礎用法和高階用法,幫助您快速上手并進一步掌握列存索引。

前提條件

  • 已開通列存索引功能。

    重要

    列存索引功能需聯系Lindorm技術支持(釘釘號:s0s3eg3)開通。

  • 已開通計算引擎。具體操作,請參見開通與變配

  • 已開通LindormDFS,且LindormDFS的版本為4.0.0及以上版本。

  • 已開通寬表引擎,且寬表引擎的版本為2.5.0及以上版本。

注意事項

  • 列存索引不支持同步構建方式

  • 列存索引的構建耗時為15分鐘左右。如果后臺索引構建任務的數量較多,業務數據量較大,那么構建列存索引的用時可能更長。

快速入門

假設要對海量數據表my_tbl進行高效并行數據分析,您需要為該表創建列存索引。

示例表my_tbl的結構如下:

+------------+-------------+---------+----------------+
| TABLE_NAME | COLUMN_NAME |  TYPE   | IS_PRIMARY_KEY |
+------------+-------------+---------+----------------+
| my_tbl     | pk0         | INT     | true           |
| my_tbl     | pk1         | VARCHAR | true           |
| my_tbl     | pt_d        | VARCHAR | true           |
| my_tbl     | col0        | INT     | false          |
| my_tbl     | col1        | VARCHAR | false          |
| my_tbl     | json_col0   | JSON    | false          |
+------------+-------------+---------+----------------+

主鍵pk0代表該行數據的標識,擁有較大的基數。主鍵pt_d表示該行數據產生的日期,通常會按照天級別進行數據分析。

  1. 創建列存索引。列存索引能自動為您展開JSON類型字段中存儲的數據。

    • 如果my_tbl的表結構比較穩定,不會頻繁發生變化。請執行以下語句:

      CREATE INDEX my_tbl_idx USING COLUMNAR
      ON my_tbl(*) 
      PARTITION BY ENUMERABLE (pt_d, bucket(128, pk0))
      WITH (
        `lindorm_columnar.user.index.database` = 'my_index_db',
        `lindorm_columnar.user.index.table` = 'my_index_tbl',
        `lindorm_columnar.user.syncer.lci.dynamicJsonColumns` = 'json_col0'
        );

      列存索引會根據您當前表結構以及json_col0的結構,來創建索引表。

    • 如果my_tbl的表結構可能會頻繁變化,請執行以下語句:

      CREATE INDEX my_tbl_idx USING COLUMNAR
      ON my_tbl(*) 
      PARTITION BY ENUMERABLE (pt_d, bucket(128, pk0))
      WITH (
        `lindorm_columnar.user.index.database` = 'my_index_db',
        `lindorm_columnar.user.index.table` = 'my_index_tbl',
        `lindorm_columnar.user.syncer.lci.dynamicJsonColumns` = 'json_col0',
        `lindorm_columnar.user.syncer.lci.dynamicSchema` = 'true');

      列存索引會根據您當前的表結構以及json_col0的結構,來創建索引表,并根據您后續的表結構、JSON字段內容變化來動態擴展索引表。

  2. 查看索引狀態。

    SHOW INDEX FROM my_tbl;

    SHOW INDEX的使用方法及返回結果集說明,請參見SHOW INDEX

  3. 使用列存索引進行數據查詢分析。具體操作,請參見使用列存索引

基礎用法

假設示例表my_tbl的結構如下:

+------------+-------------+---------+----------------+
| TABLE_NAME | COLUMN_NAME |  TYPE   | IS_PRIMARY_KEY |
+------------+-------------+---------+----------------+
| my_tbl     | pk0         | INT     | true           |
| my_tbl     | pk1         | VARCHAR | true           |
| my_tbl     | pk2         | VARCHAR | true           |
| my_tbl     | col0        | INT     | false          |
| my_tbl     | col1        | VARCHAR | false          |
+------------+-------------+---------+----------------+

創建列存索引

語法

CREATE INDEX index_name USING COLUMNAR
ON table_name(column_name(,..))
PARTITION BY ENUMERABLE (column_name(,...), bucket(bucket_num, column_name))
WITH (`lindorm_columnar.user.index.database` = 'columnar_db_name',
      `lindorm_columnar.user.index.table` = 'columnar_tbl_name');

參數說明

參數

說明

index_name

列存索引的名稱,由大寫字母、小寫字母、數字、下劃線(_)其中的一種或多種組成。

table_name

寬表名稱。

column_name(,...))

需要創建列存索引的字段列表,多個字段用英文逗號(,)分隔。目前支持創建列存索引的字段類型包括:TINYINT、SMALLINT、INTEGER、BIGINT、LONG、FLOAT、DOUBLE、VARCHAR、BINARY、VARBINARY、BOOLEAN。

說明

該字段列表必須包含對應寬表的全部主鍵字段,若您需要為全部字段(主鍵和非主鍵)創建列存索引,可簡寫為(*)

PARTITION BY ENUMERABLE(column_name(,...), bucket(bucket_num, column_name))

指定索引數據按照枚舉算法進行分區,從而提升查詢過程中的檢索能力。分區表達式包括普通分區表達式和bucket分區表達式,且普通分區表達式和bucket分區表達式中的字段均為寬表主鍵字段。

  • 普通分區表達式

    • 可以指定0個或多個普通分區表達式,多個表達式用英文逗號(,)分隔。

    • 普通分區表達式為寬表主鍵字段(例如城市、日期等),索引數據會按照不同的分區值構建,并在查詢時按照分區過濾條件高效定位數據。

  • bucket分區表達式

    • 至少指定1個bucket分區表達式。

    • bucket_num為bucket分區數目,column_name為bucket分區字段,用于計算bucket分區號(bucket_index)。bucket_index的計算方法為基于表達式中的bucket分區字段計算hash值,然后對bucket_num取余得出。在下面的示例中,bucket_index的計算方法為hash(pk0)%128

    • bucket分區字段需為寬表中的主鍵字段,并確保bucket分區字段具有足夠的離散特征,避免不同分區間的數據傾斜。

    普通分區表達式和bucket分區表達式共同決定了索引數據的分區數量,建議將每個分區的數據量設置在50 MB到512 MB之間。例如:普通分區表達式為日期字段dt,寬表單日數據量為50 GB,寬表主鍵字段為(id, dt),可以將分區表達式配置為PARTITION BY ENUMERABLE (dt, bucket(200, id))

WITH(`key` = 'value')

使用WITH關鍵字為列存索引指定以下參數:

  • lindorm_columnar.user.index.database:指定列存索引表所在Database名稱。

  • lindorm_columnar.user.index.table:指定列存索引表名稱。

示例

以表my_tbl為例創建列存索引:

CREATE INDEX my_tbl_idx USING COLUMNAR
ON my_tbl(pk0, pk1, pk2, col0, col1)
PARTITION BY ENUMERABLE (pk1, pk2, bucket(128, pk0))
WITH (`lindorm_columnar.user.index.database` = 'my_index_db',
      `lindorm_columnar.user.index.table` = 'my_index_tbl');

查看列存索引

列存索引創建成功后,索引數據會持續構建,寬表作為主表會持續將表中的數據同步至列存索引表中。數據同步包括存量數據同步和增量數據同步,增量數據同步過程中,索引數據與主表的數據會存在延遲,延遲時間小于1小時。

您可以通過SHOW INDEX語句查看列存索引的狀態。SHOW INDEX的使用方法及返回結果集說明,請參見SHOW INDEX

使用列存索引

創建列存索引可以增強寬表海量數據的分析計算能力,您可以在SELECT查詢語句中指定相關HINT參數,將查詢請求路由至計算引擎執行并使用列存索引加速查詢,從而提升大數據計算的效率。HINT參數的詳細說明和使用方式,請參見通過HINT方式使用資源組

示例一:大數據統計

SELECT /*+ _use_ldps_(cg0), _columnar_index_ */ COUNT(*), SUM(col0), MIN(col0), MAX(col0)
FROM my_index_db.my_index_tbl
WHERE col0 > 100 AND col0 < 200 OR col0 > 500
GROUP BY pk1;

示例二:大數據排序

SELECT /*+ _use_ldps_(cg0), _columnar_index_ */ pk0 + col0, pk1
FROM my_index_db.my_index_tbl
WHERE col0 > 100 AND col0 < 200 OR col0 > 500
ORDER BY pk1
LIMIT 100;

示例三:大數據關聯

如果您為多個寬表創建了列存索引,也可以將寬表間的數據進行關聯。

SELECT /*+ _use_ldps_(cg0), _columnar_index_ */ *
FROM my_index_db.my_index_tbl0 as t0
  JOIN my_index_db.my_index_tbl1 as t1 
ON t0.pk0 = t1.pk0
AND t0.pk1 = t1.pk1
LIMIT 100;

刪除列存索引

您可以通過DROP INDEX語句刪除指定的列存索引。DROP INDEX的使用方法及示例,請參見DROP INDEX

進階用法

復雜分區表達式

假設示例表my_ts_tbl的表結構如下:

+------------+-------------+---------+----------------+
| TABLE_NAME | COLUMN_NAME |  TYPE   | IS_PRIMARY_KEY |
+------------+-------------+---------+----------------+
| my_ts_tbl  | id          | INT     | true           |
| my_ts_tbl  | ts          | LONG    | true           |
| my_ts_tbl  | col0        | VARCHAR | false          |
| my_ts_tbl  | col1        | INT     | false          |
+------------+-------------+---------+----------------+

在創建列存索引時,若寬表數據的主鍵字段不能直接作為列存索引的普通分區表達式,可以在普通分區表達式中包含計算邏輯,示例如下。

  • 對寬表所有字段創建列存索引,將列存索引數據按時間戳字段ts按天分區:

    CREATE INDEX my_ts_idx USING COLUMNAR ON my_ts_tbl(*)
    PARTITION BY ENUMERABLE (ifnull(substring(from_unixtime(ts), 0, 10), 'unknown') AS dt, bucket(128, id))
    WITH (`lindorm_columnar.user.index.database` = 'my_ts_index_db',
          `lindorm_columnar.user.index.table` = 'my_ts_index_tbl');
  • 列存索引創建完成后,您可以在查詢語句中指定過濾條件并查詢列存索引中的數據。

    SELECT /*+ _use_ldps_ */ COUNT(1)
    FROM lindorm_columnar.my_ts_index_db.my_ts_index_tbl
    WHERE dt = '2020-06-06';

僅為增量數據構建列存索引

如果您需要跳過寬表中的存量數據,只為增量數據構建列存索引,可以指定參數lindorm_columnar.user.syncer.skip.fullsync = 'true',示例如下:

CREATE INDEX my_tbl_idx USING COLUMNAR ON my_tbl(*)
PARTITION BY ENUMERABLE (pk1, pk2, bucket(128, pk0))
WITH (`lindorm_columnar.user.index.database` = 'my_index_db',
      `lindorm_columnar.user.index.table` = 'my_index_tbl',
      `lindorm_columnar.user.syncer.skip.fullsync` = 'true');

JSON字段展開存儲

列存索引支持在數據同步時,將JSON類型的字段展開存儲,支持靜態展開存儲動態展開存儲兩種方式。

假設示例表my_json_tbl的表結構如下:

+-------------+-------------+--------+----------------+
| TABLE_NAME  | COLUMN_NAME |  TYPE  | IS_PRIMARY_KEY |
+-------------+-------------+--------+----------------+
| my_json_tbl | id          | BIGINT | true           |
| my_json_tbl | col1        | INT    | false          |
| my_json_tbl | json_col    | JSON   | false          |
+-------------+-------------+--------+----------------+

執行以下語句插入JSON數據:

UPSERT INTO my_json_tbl (id,col1,json_col) VALUES(2,2,'{"a": {"b": {"c": "hello,world", "d": 123}, "e": false }, "f": 3.14}');

json_col的結構如下:

單擊查看JSON列數據結構

{
  "a": {
    "b": {
      "c": "hello,world",
      "d": 123
    },
    "e": false
  },
  "f": 3.14
}

靜態展開存儲

在創建列存索引時,您可以指定`lindorm_columnar.user.syncer.lci.jsonMapping.<JSON_COL>` = '<JSON_MAPPING_RULE>',來定義寬表JSON字段到列存表字段之間的靜態映射關系。示例如下:

CREATE INDEX columnar_idx USING COLUMNAR ON my_json_tbl(*) 
PARTITION BY ENUMERABLE (ifnull(id%16, 0) as dt, bucket(16,id)) 
WITH (
  `lindorm_columnar.user.syncer.lci.jsonMapping.json_col` = 'a.b.c VARCHAR, a.e BOOLEAN ,f DOUBLE',
  `lindorm_columnar.user.index.database` = 'my_index_db',
  `lindorm_columnar.user.index.table` = 'my_index_tbl');
說明
  • lindorm_columnar.user.syncer.lci.jsonMapping.json_col:指定需要靜態展開的JSON列,此處指定列json_col

  • a.b.c VARCHAR,a.e BOOLEAN ,f DOUBLE:指定每一個展開字段,使用英文逗號(,)隔開。

    • 字段名:展開字段對應的JSON路徑,使用半角句號(.)隔開。例如a.b.c

    • 字段類型:支持的數據類型為BOOLEAN、BYTE、SHORT、INTEGER、LONG、FLOAT、DOUBLE和VARCHAR。

  • 您可以通過WITH關鍵字指定多個lindorm_columnar.user.syncer.lci.jsonMapping,為多個JSON字段創建映射。

  • 同一個JSON字段不能同時定義在靜態展開映射與動態展開映射中。

動態展開存儲(公測中)

在創建列存索引時,您可以指定`lindorm_columnar.user.syncer.lci.dynamicJsonColumns` = '<JSON_COL1>,<JSON_COL2>',來定義寬表JSON字段動態展開映射到列存表。示例如下:

CREATE INDEX columnar_idx USING COLUMNAR ON my_json_tbl(*) 
PARTITION BY ENUMERABLE (ifnull(id%16, 0) as dt, bucket(16,id)) 
WITH (
  `lindorm_columnar.user.syncer.lci.dynamicJsonColumns` = 'json_col',
  `lindorm_columnar.user.index.database` = 'my_index_db',
  `lindorm_columnar.user.index.table` = 'my_index_tbl');
說明
  • lindorm_columnar.user.syncer.lci.dynamicJsonColumns:指定需要動態展開的JSON列,此處指定列為json_col。支持指定多個動態展開的JSON列,使用英文逗號(,)隔開,例如json_col1,json_col2

  • 列存索引將根據JSON中實際存儲類型來推斷列存表的數據類型,推斷類型僅支持BOOLEAN、LONG、DOUBLE和STRING。如果您的數據值中有多種類型字段,則列存表使用STRING類型來存儲。

  • 對于存量數據構建列存索引時,不支持JSON字段動態展開

  • 同一個JSON字段不能同時定義在靜態展開映射與動態展開映射中。

當您為JSON字段配置為靜態展開存儲或者動態展開存儲后,原始JSON字段將不會存儲到列存表中。同時,列存表存儲的JSON展開名會以其對應JSON字段名為前綴。

例如當您通過`lindorm_columnar.user.syncer.lci.jsonMapping.json_col` = 'a.b.c VARCHAR, a.e BOOLEAN',為列存索引指定JSON靜態展開存儲后。此時列存表中將不會有名為json_col的列,而會有以下列:

  • 名為json_col.a.b.c的列:類型為STRING,存儲json_col字段中a.b.c的值。

  • 名為json_col.a.e的列:類型為BOOLEAN,存儲json_col字段中a.e的值。

如果您仍希望同步原始JSON字段,或不期望列存表存儲的JSON展開字段名以對應JSON字段名為前綴,可以通過以下方式實現:

同步原始JSON字段

如果您仍然需要同步原始JSON字段,請在創建索引時指定 `lindorm_columnar.user.syncer.lci.json.syncOriginalJsonContent` = 'true'。此時,列存表中會有以下列:

  • 名為json_col的列:類型為STRING,存儲json_col字段的值。

  • 名為json_col.a.b.c的列:類型為STRING,存儲json_col字段中a.b.c的值。

  • 名為json_col.a.e的列:類型為BOOLEAN,存儲json_col字段中a.e的值。

指定列存表的字段名忽略JSON字段名前綴

如果您不期望列存表存儲的JSON展開字段名會以其對應JSON字段名為前綴,請在創建索引時指定`lindorm_columnar.user.syncer.lci.json.ignoreJsonMappingPrefix` = 'true'。此時,列存表中會有以下列:

  • 名為a.b.c的列:類型為STRING,存儲json_col字段中a.b.c的值。

  • 名為a.e的列:類型為BOOLEAN,存儲json_col字段中a.e的值。

重要

如果在不同的JSON字段中存在相同的映射信息(例如json_col1json_col2中均指定需要展開存儲a.b.c的值),則會導致列存索引創建失敗。

表結構變更動態感知(公測中)

列存索引可以在數據同步時,動態感知數據表的表結構變更,并影響列存表的表結構。在創建列存索引時,您可以指定`lindorm_columnar.user.syncer.lci.dynamicSchema` = 'true',來定義列存表結構與主表結構保持一致。示例如下:

CREATE INDEX my_tbl_idx USING COLUMNAR
ON my_tbl(*) 
PARTITION BY ENUMERABLE (pt_d, bucket(128, pk0))
WITH (
  `lindorm_columnar.user.index.database` = 'my_index_db',
  `lindorm_columnar.user.index.table` = 'my_index_tbl',
  `lindorm_columnar.user.syncer.lci.dynamicSchema` = 'true');

為列存表添加列(公測中)

創建列存索引后,您可以通過ALTER INDEX語法為列存索引添加字段而無需重建索引,支持為列存索引添加普通字段或者JSON字段靜態展開的Mapping列。

假設表my_json_tbl的結構如下:

+-------------+-------------+---------+----------------+
|  TABLE_NAME | COLUMN_NAME |  TYPE   | IS_PRIMARY_KEY |
+-------------+-------------+---------+----------------+
| my_json_tbl | id          | BIGINT  | true           |
| my_json_tbl | col1        | INT     | false          |
| my_json_tbl | col2        | VARCHAR | false          |
| my_json_tbl | json_col1   | JSON    | false          |
| my_json_tbl | json_col2   | JSON    | false          |
+--------------+-------------+---------+----------------+

您可以通過以下SQL語句創建列存索引:

CREATE INDEX columnar_idx USING COLUMNAR ON my_json_tbl(id, col1, json_col1) 
PARTITION BY ENUMERABLE (ifnull(id%16, 0) as dt, bucket(16,id)) 
WITH (
  `lindorm_columnar.user.syncer.lci.jsonMapping.json_col1` = 'a.b.c VARCHAR, a.e BOOLEAN',
  `lindorm_columnar.user.index.database` = 'my_index_db',
  `lindorm_columnar.user.index.table` = 'my_index_tbl');

此時,在列存表中未包含 col2json_col2相關的列。您可以通過以下語句為列存索引添加普通字段:

ALTER INDEX IF EXISTS columnar_idx ON my_json_tbl ADD COLUMNS(col2);

您也可以通過以下語句為列存索引添加JSON字段的靜態映射規則:

ALTER INDEX IF EXISTS columnar_idx ON my_json_tbl
ADD COLUMNS (
  json_extract_long(json_col2, '$.key1'),
  json_extract_boolean(json_col2, '$.key2'),
  json_extract_double(json_col2, '$.key3.key4')
);
說明

目前僅支持json_extract_booleanjson_extract_longjson_extract_doublejson_extract_string提取函數。

常見問題

  • Q:創建列存索引后,是否會產生額外費用?

    A:會。主要包括列存索引數據的存儲費用,以及主表和列存索引之間數據同步實際使用的CU費用。

  • Q:分區表達式中是否可以包含非主鍵字段?

    A:不可以。分區表達式中的字段必須全部為主鍵字段。

  • Q:bucket分區表達式中,是否可以包含復雜分區表達式?

    A:不可以。bucket分區表達式中僅包括bucket_numbucket分區字段。

  • Q:分區數目過大或過小會有什么影響?

    A:分區數目過大,會導致元數據膨脹,從而影響查詢效率,因此建議單分區數據量大于50 MB,bucket分區表達式中的bucket_num小于1024。分區數目過小,會影響數據讀寫吞吐或造成數據傾斜,建議單分區數據量小于512 MB。

  • Q:是否可以通過Lindorm計算引擎直接訪問列存索引數據?

    A:可以。您需要先自定義索引表的名稱再通過計算引擎訪問列存索引數據。具體操作,請參見訪問列存數據

    重要

    請謹慎執行列存索引表的修改操作,如需修改列存索引表,請聯系Lindorm技術支持(釘釘號:s0s3eg3)。

  • Q:能否為同一個寬表創建多個列存索引?

    A:不能。一張寬表僅支持創建一個列存索引。

  • Q:寬表中數據因為TTL過期被清除后,列存索引數據是否會被自動清除?

    A:不會。

  • Q:列存索引創建失敗了,再次創建為什么會報錯?

  • A:一張寬表僅允許創建一個列存索引,無論該索引的狀態是否為失敗。您需要先刪除構建失敗的列存索引,再去創建新的索引。刪除列存索引的語法,請參見DROP INDEX