Posted by Socrates on | Featured
作为开源实时数据仓库,Apache Doris 提供丰富的索引选择来加速数据扫描和过滤。根据用户参与程度,可以分为内置智能索引和用户创建索引。前者是 Apache Doris 在数据摄取时自动生成的,例如 ZoneMap 索引和前缀索引,而后者是用户针对各种用例选择的索引,包括倒排索引和 NGram BloomFilter 索引。
这篇文章深入探讨了倒排索引和 NGram BloomFilter 索引,提供了将它们应用于各种查询。
示例数据集
测试数据集包含约 1.3 亿条亚马逊客户评论。这是几个 Snappy 压缩的 Parquet 文件,总大小为 37GB。以下是一些示例:
每行包含 15 列,包括 customer_id
、review_id
、product_id
、product_category
、star_ rating
、review_headline
和 review_body
。
其中许多列可以通过基于其结构的索引来加速。例如,customer_id
是一个高基数数字字段,而 product_id
是一个低基数固定长度文本字段,而 product_title
和 < code>review_body 分别是短文本字段和长文本字段。
对这些列的查询大致可以分为两种类型:
- 文本搜索:搜索
review_body
字段中的某些内容。
- 非主键列查询:查询有关特定
product_id
或来自特定customer_id
的评论。
这些也是本文的主线。我将向您介绍索引如何加速这些查询。
先决条件
为了快速运行,这里我们使用单节点集群(1 个前端,1 个后端)。
- 部署 Apache Doris:参考快速入门< /里>
- 使用以下语句创建表:
创建表 `amazon_reviews` (
`review_date` int(11) NULL,
`市场` varchar(20) NULL,
`customer_id` bigint(20) NULL,
`review_id` varchar(40) NULL,
`product_id` varchar(10) NULL,
`product_parent` bigint(20) NULL,
`产品标题` varchar(500) NULL,
`产品类别` varchar(50) NULL,
`star_ rating`smallint(6) NULL,
`helpful_votes` int(11) NULL,
`total_votes` int(11) NULL,
`vine` 布尔值 NULL,
`verified_purchase` 布尔值 NULL,
`review_headline` varchar(500) NULL,
`review_body` 字符串 NULL
) 引擎=OLAP
重复密钥(`review_date`)
评论“OLAP”
按哈希(`review_date`)分布 桶 16
特性 (
"replication_allocation" = "tag.location.default: 1",
“压缩”=“ZSTD”
);
-
下载数据集:Snappy 压缩的 Parquet 文件,总大小为 37GB
- 执行以下命令加载数据集
curl --location-trusted -u root: -T amazon_reviews_2010.snappy.parquet -H "format:parquet" http://${BE_IP}:${ BE_PORT}/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2011.snappy.parquet -H "format:parquet" http://${BE_IP}:${BE_PORT}/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2012.snappy.parquet -H "format:parquet" http://${BE_IP}:${BE_PORT}/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2013.snappy.parquet -H "format:parquet" http://${BE_IP}:${BE_PORT}/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2014.snappy.parquet -H "format:parquet" http://${BE_IP}:${BE_PORT}/api/${DB}/amazon_reviews/_stream_load
curl --location-trusted -u root: -T amazon_reviews_2015.snappy.parquet -H "format:parquet" http://${BE_IP}:${BE_PORT}/api/${DB}/amazon_reviews/_stream_load代码>前>
- 检查验证:完成上述步骤后,在MySQL客户端中执行以下语句检查数据集的大小。从下面可以看出,加载了 135589433 行,在 Apache Doris 中占用了 25.873GB,比原始 Parquet 文件小了 30%。
mysql> SELECT COUNT() FROM amazon_reviews;
+------------+
|计数(*)|
+------------+
| 135589433 |
+------------+
一组 1 行(0.02 秒)
mysql> 显示来自 amazon_reviews 的数据;
+----------------+----------------+------------------------+--- -----------+------------+------------+
|表名 |索引名称 |尺寸|副本计数 |行数 |远程尺寸 |
+----------------+----------------+------------------------+--- -----------+------------+------------+
|亚马逊评论 |亚马逊评论 | 25.873 GB | 16 | 16 135589433 | 0.000 | 0.000
| |总计 | 25.873 GB | 16 | 16 | 0.000 | 0.000
+----------------+----------------+------------------------+--- -----------+------------+------------+
2 行一组(0.00 秒)
加速文本搜索
无索引
现在,让我们尝试在 review_body
字段上运行文本搜索。具体来说,我们正在尝试检索评论中包含关键字“is super Awesome”的前 5 个产品。结果应根据评论数量按降序排序。每个结果应包含产品 ID、随机选择的产品标题、平均星级和评论总数。
这是查询语句:
选择
产品ID,
任何(产品标题),
AVG(star_ rating) AS 评级,
COUNT() AS 计数
从
亚马逊评论
在哪里
review_body LIKE '%超级棒%'
通过...分组
产品编号
订购依据
计数 DESC,
评级 DESC,
产品编号
限制 5;
由于 review_body
字段包含冗长的评论,因此此类文本搜索可能非常耗时。在不启用任何索引的情况下,需要 7.6 秒返回结果:
+------------------------+------------------------ --------------------+--------------------+-------- +
|产品 ID |任何值(产品标题)|评级|计数|
+------------+------------------------------------ ------+--------------------+--------+
| B00992CF6W | B00992CF6W |我的世界 | 4.8235294117647056 | 17 | 17
| B009UX2YAC |地铁跑酷 | 4.7777777777777777 | 9 |
| B00DJFIMW6 |小黄人快闪:卑鄙的我官方游戏 | 4.875 | 4.875 8 |
| B0086700CM |神庙逃亡 | 5 | 6 |
| B00KWVZ750 |愤怒的小鸟史诗角色扮演游戏 | 5 | 6 |
+------------+------------------------------------ ------+--------------------+--------+
一组 5 行(7.60 秒)
NGram BloomFilter 索引
现在,让我们尝试使用 NGram BloomFilter 索引加速此类文本搜索。
gram_size
:“NGram”中“N”的值,表示连续字符的长度。在下面的代码片段中,"gram_size"="10"
表示文本将被分为许多 10 个字符的字符串,这是 NGram BloomFilter 索引的基础。
bf_size
:BloomFilter 的大小(以字节为单位)。 "bf_size"="10240"
表示BloomFilter占用10240字节的空间。
使用 NGRAM_BF PROPERTIES("gram_size"="10", "bf_size"="10240") 更改表 amazon_reviews 添加索引 review_body_ngram_idx(review_body);
< /前>
这次,查询在0.93秒内完成。这意味着 NGram BloomFilter 带来了 8 倍的加速。
+------------------------+------------------------ --------------------+--------------------+-------- +
|产品 ID |任何值(产品标题)|评级|计数|
+------------+------------------------------------ ------+--------------------+--------+
| B00992CF6W | B00992CF6W |我的世界 | 4.8235294117647056 | 17 | 17
| B009UX2YAC |地铁跑酷 | 4.7777777777777777 | 9 |
| B00DJFIMW6 |小黄人快闪:卑鄙的我官方游戏 | 4.875 | 4.875 8 |
| B0086700CM |神庙逃亡 | 5 | 6 |
| B00KWVZ750 |愤怒的小鸟史诗角色扮演游戏 | 5 | 6 |
+------------+------------------------------------ ------+--------------------+--------+
一组 5 行(0.93 秒)
那么 NGram BloomFilter 是如何发挥魔力的呢? 它的工作方式可以分为两部分来解释。
- NGram 标记化:当
gram_size=5
时,短语“hello world”被拆分为 [“hello”, “ello”, “llo w”、“lo wo”、“o wor”、“worl”、“世界”]。然后对这些子字符串进行哈希处理并将其添加到 bf_size
的 BloomFilter 中。由于 Apache Doris 中的数据是按页存储的,因此 BloomFilter 也是按页生成的。
- 查询加速:例如查询文本中的单词“hello”,将“hello”进行标记并与每个页面的BloomFilter进行比较。如果 BloomFilter 检测到页面中的潜在匹配(可能存在误报),则会加载该页面以进行进一步匹配。否则,该页面将被跳过。
BloomFilter索引通过跳过不相关的页面,减少了不必要的数据扫描,从而大大降低了查询延迟。
NGram BloomFilter 插图< /跨度>跨度>
NGram BloomFilter 说明
如何找到 NGram BloomFilter 的最佳参数配置
gram_size
决定匹配效率,而bf_size
影响误报率。通常,较大的 bf_size
会降低误报率,但也需要更多的存储空间。因此,我们建议您根据以下两个因素来配置这两个参数:
文本长度
- 对于短文本(单词或短语),建议使用较小的
gram_size
(2~4) 和较小的 bf_size
。
- 对于长文本(句子或段落),较大的
gram_size
(5~10) 和较大的 bf_size
效果更好。
查询模式
- 如果查询经常涉及短语或完整单词,则较大的
gram_size
会更有效。
- 对于模糊匹配或多样化查询,较小的
gram_size
可以实现更灵活的匹配。
倒排索引
倒排索引 是加速文本搜索的另一种方法。创建倒排索引很简单:
- 添加倒排索引:请参阅下面的代码段为
amazon_reviews
review_body 列创建倒排索引代码>表。倒排索引支持短语搜索,其中标记词的顺序会影响搜索结果。
- 为历史数据添加倒排索引:您还可以为历史数据创建倒排索引。
更改表 amazon_reviews 添加索引 review_body_inverted_idx(`review_body`)
使用反向属性("parser" = "english","support_phrase" = "true");
在 amazon_reviews 上构建索引 review_body_inverted_idx;
- 检查并验证:您可以使用以下语句检查并查看创建的索引:
mysql> 显示构建索引 WHERE TableName="amazon_reviews";
+-------+----------------+----------------+----- -------------------------------------------------- -------------------------------------------------- ------------------------+------------------------- +------------------------+----------------+-------- ---+------+----------+
|职位编号 |表名 |分区名称 |更改倒排索引 |创建时间 |完成时间 |交易ID |状态|留言 |进展|
+-------+----------------+----------------+----- -------------------------------------------------- -------------------------------------------------- ------------------------+------------------------- +------------------------+----------------+-------- ---+------+----------+
| 10152 | 10152亚马逊评论 |亚马逊评论 | [添加索引 review_body_inverted_idx (
评论正文
) 使用反向属性("parser" = "english", "support_phrase" = "true")], | 2024-01-23 15:42:28.658 | 2024-01-23 15:48:42.990 | 11 | 11完成 | |空|
+-------+----------------+----------------+----- -------------------------------------------------- -------------------------------------------------- ------------------------+------------------------- +------------------------+----------------+-------- ---+------+----------+
一组 1 行(0.00 秒)
如果您想了解标记化的工作原理,可以使用TOKENIZE
函数进行测试。只需输入需要标记化的文本和参数即可:
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
| tokenize('我可以诚实地给予发货和包装 100%,它准时到达,没有任何问题,而且这本书状况完美。超级棒的购买,非常适合我的大学课程', '"parser " = "english","support_phrase" = "true"') |
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
| [“我”,“可以”,“诚实”,“给予”,“该”,“装运”,“和”,“包裹”,“100”,“它”,“来了”,“在”,“时间”、“那个”、“它”、“是”、“应该”、“到”、“与”、“不”、“哈塞尔”、“和”、“那个”、“书”、“是” 、“在”、“完美”、“状况”、“超级”、“棒极了”、“购买”、“和”、“优秀”、“对于”、“我的”、“学院”、“课程”] |
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
1 行一组(0.05 秒)
“ data-lang =“text / x-mysql”>
mysql> SELECT TOKENIZE('我可以诚实地给予货物和包裹 100%,它准时到达,没有任何问题,而且这本书已经在完美的条件。
超级棒的购买,非常适合我的大学课程', '"parser" = "english","support_phrase" = "true"');
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
| tokenize('我可以诚实地给予发货和包装 100%,它准时到达,没有任何问题,而且这本书状况完美。超级棒的购买,非常适合我的大学课程', '"parser " = "english","support_phrase" = "true"') |
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
| [“我”,“可以”,“诚实”,“给予”,“该”,“装运”,“和”,“包裹”,“100”,“它”,“来了”,“在”,“时间”、“那个”、“它”、“是”、“应该”、“到”、“与”、“不”、“哈塞尔”、“和”、“那个”、“书”、“是” 、“在”、“完美”、“状况”、“超级”、“棒极了”、“购买”、“和”、“优秀”、“对于”、“我的”、“学院”、“课程”] |
+------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------+
1 行一组(0.05 秒)
通过倒排索引,我们现在可以使用 MATCH_PHRASE
检索包含“is super Awesome”的客户评论。
选择
产品ID,
任何(产品标题),
AVG(star_ rating) AS 评级,
COUNT() AS 计数
从
亚马逊评论
在哪里
review_body MATCH_PHRASE '超级棒'
通过...分组
产品编号
订购依据
计数 DESC,
评级 DESC,
产品编号
限制 5;
子句 review_body MATCH_PHRASE 'is super Awesome'
搜索 review_body
列中包含所有三个关键字“is”、“super”和“awesome”的文本片段" 按照这个确切的顺序,中间没有其他单词。
MATCH
查询不区分大小写,这也是它与 LIKE
查询的区别。 MATCH
查询在大型数据集中更加高效。
结果显示,倒排索引将查询延迟降低至0.19秒,相比NGram BloomFilter索引带来4倍的性能提升,比完全没有索引的性能提升近40倍。
+------------------------+------------------------ --------------------+--------------------------------+-----+
|产品 ID |任何值(产品标题)|评级|计数|
+------------+------------------------------------ ------+--------------------+--------------------+
| B00992CF6W | B00992CF6W |我的世界 | 4.833333333333333 | 18 | 18
| B009UX2YAC |地铁跑酷 | 4.7 | 4.7 10 | 10
| B00DJFIMW6 |小黄人快闪:卑鄙的我官方游戏 | 5 | 7 |
| B0086700CM |神庙逃亡 | 5 | 6 |
| B00KWVZ750 |愤怒的小鸟史诗角色扮演游戏 | 5 | 6 |
+------------+------------------------------------ ------+--------------------+--------------------+
一组 5 行(0.19 秒)
倒排索引是如何实现的?
倒排索引将文本拆分为单词并将每个单词映射到行号。然后,标记化的单词按字母顺序排序并创建跳跃列表索引。当执行特定单词的查询时,系统使用跳表索引和二分查找方法在这个有序映射中定位行号。根据行号,系统检索整个数据记录。
这种方法避免了逐行匹配,并将计算复杂度从 O(n) 降低到 O(logn)。这就是倒排索引加速大型数据集查询的方式。
倒排索引说明
为了更深入地理解倒排索引,我将从它的读/写逻辑开始。在Doris中,从逻辑上讲,倒排索引应用在表的列级别。然而,从物理存储和实现的角度来看,它实际上是建立在数据文件之上的。
- 写入:数据写入数据文件时,也会同步写入倒排索引文件,并匹配行号。
- 查询:查询时,如果
WHERE
条件涉及到已建倒排索引的列,Doris会直接走到索引文件并返回相应的行号。然后,根据行号,它会跳过不相关的页和行,只读取目标行。
简而言之,倒排索引通过映射实现高速文本搜索,其实现依赖于数据文件和索引文件的配合。
加速非主键列查询
为了展示倒排索引对非主键列查询的影响,让我们尝试一些多维查询。
无索引
检索客户 ID 13916588 关于产品 ID B002DMK1R0 的评论。如果没有索引,系统必须扫描整个表。查询在1.81秒内完成。
mysql> 选择产品标题、评论标题、评论正文、星级评级
来自亚马逊评论
WHERE Product_id='B002DMK1R0' AND customer_id=13916588;
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
|产品标题 |评论标题 |评论正文 |星级 |
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
| Magellan Maestro 4700 4.7 英寸蓝牙便携式 GPS 导航仪 | Magellan Maestro 4700不错的功能但是... |这是一个很棒的 GPS。带您到达目的地。不过,不要忘记为交通套件购买单独的(哎呀!)电线! | 4 |
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
一组 1 行(1.81 秒)
倒排索引
此查询的执行方式与上面所说的不同,因为系统不必对 product_id
和 customer_id
进行标记,而是创建一个倒置的 Value→RowID索引表。
首先,通过以下语句创建倒排索引:
更改表 amazon_reviews 添加索引 Product_id_inverted_idx(product_id) 使用 INVERTED ;
更改表 amazon_reviews 添加索引 customer_id_inverted_idx(customer_id) 使用 INVERTED ;
在 amazon_reviews 上构建索引product_id_inverted_idx;
在 amazon_reviews 上构建索引 customer_id_inverted_idx;
使用倒排索引,相同的查询在0.06秒内完成。与之前的 1.81 秒相比,这意味着速度提高了30 倍。
mysql> 从 amazon_reviews 中选择product_title、review_headline、review_body、star_ rating,其中product_id='B002DMK1R0' AND customer_id='13916588';
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
|产品标题 |评论标题 |评论正文 |星级 |
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
| Magellan Maestro 4700 4.7 英寸蓝牙便携式 GPS 导航仪 | Magellan Maestro 4700不错的功能但是... |这是一个很棒的 GPS。带您到达目的地。不过,不要忘记为交通套件购买单独的(哎呀!)电线! | 4 |
+------------------------------------------------ ----------------+--------------------+---------- -------------------------------------------------- -------------------------------------------------- ---------------+-------------+
一组 1 行(0.06 秒)
简介
这是 SegmentIterator Profile 的摘录,从中您可以了解为什么倒排索引可以加速查询执行。
(注意,如果需要查看某个查询的Profile,请确保在执行该查询之前已在MySQL客户端中执行了SET enable_profile=true;
,然后才能查看该查询的Profile位于http://FE_IP:FE_HTTP_PORT/QueryProfile)
SegmentIterator:
- FirstReadSeekCount:0
- 首次读取查找时间:0ns
- 首次读取时间:13.119ms
- IO定时器:19.537ms
- InvertedIndexQueryTime:11.583ms
- 原始行读取:1
- 筛选的行条件:0
-行InvertedIndexFiltered:16.907403M(16907403)
- 行ShortCircuitPredInput:0
- RowsVectorPredFiltered:0
- 行向量预测输入:0
- 短预测评估时间:0ns
- 总页数:27
- 未压缩字节读取:3.71 MB
- VectorPredEvalTime:0ns
RowsInvertedIndexFiltered: 16.907403M (16907403)
和 RawRowsRead: 1
表示倒排索引过滤掉了 16907403 行,只读取了 1 行(目标行)。 FirstReadTime: 13.119ms
表示读取目标行所在页面需要13.119ms,InvertedIndexQueryTime: 11.583ms
表示系统过滤掉16907403仅 11.58 毫秒内的行。
作为比较,这是不使用索引时的 SegmentIterator Profile:
SegmentIterator:
- FirstReadSeekCount:9.374K (9374)
- 首次读取搜索时间:400.522ms
- 首次读取时间:3s144ms
- IO定时器:2s564ms
- InvertedIndexQueryTime:0ns
- 原始行读取:16.680706M (16680706)
- 筛选的行条件:226.698K (226698)
- 行反向索引过滤:0
- 行ShortCircuitPredInput:1
- RowsVectorPredFiltered:16.680705M (16680705)
- RowsVectorPredInput:16.680706M (16680706)
- RowsZonemapFiltered:226.698K (226698)
- 短预测评估时间:2.723ms
- 总页数:5.421K (5421)
- 未压缩字节读取:277.05 MB
- VectorPredEvalTime:8.114ms
不使用倒排索引,加载 16680706 行需要 3.14 秒(FirstReadTime: 3s144ms
)。然后,系统通过Predicate Evaluate进行过滤,筛选出16680705行。条件过滤过程仅需不到10ms,使得原始数据加载成为最耗时的任务。
总而言之,倒排索引通过快速检索目标行来提高查询执行效率,从而减少不必要的数据加载。
加速低基数文本列查询
所以倒排索引对于高基数文本列的查询来说是一个很大的加速器,但这可能会引起一个问题:对于低基数列,太多的索引会带来过多的开销并降低查询性能吗?
答案是:不。让我向您展示原因和方式。以下示例使用product_category
作为过滤的谓词列。
mysql> 从 amazon_reviews 中选择 COUNT(DISTINCT Product_category) ;
+----------------------------------+
|计数(不同的产品类别)|
+----------------------------------+
| 43 | 43
+----------------------------------+
一组 1 行(0.57 秒)
如图所示,product_category
列只有 43 个不同的类别,使其成为典型的低基数文本列。现在,让我们为其添加倒排索引。
更改表 amazon_reviews 使用 INVERTED 添加索引 Product_category_inverted_idx(`product_category`);
在 amazon_reviews 上构建索引product_category_inverted_idx;
添加倒排索引后,运行以下 SQL 查询来检索“Mobile_Electronics”产品类别中评论最多的前 3 个产品。
选择
产品ID,
产品标题,
AVG(star_ rating) AS 评级,
任何(评论正文),
任何(评论标题),
COUNT(*) AS 计数
从
亚马逊评论
在哪里
产品类别 = '移动电子'
通过...分组
产品标题、产品 ID
订购依据
计数 DESC
限制 10;
使用倒排索引,查询需要1.54s完成。
+------------------------+------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------+-------------------- +------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------------------------------------------------+-------- ------------------------+--------------------+
|产品 ID |产品标题 |评级|任何_值(评论正文)|任何值(评论标题)|计数|
+------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------+--------------------+-------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------+------------------------ ----------+--------+
| B00J46XO9U | iXCC Lightning 数据线 3 英尺,iPhone 充电器,适用于 iPhone X、8、8 Plus、7、7 Plus、6s、6s Plus、6、6 Plus、SE 5s 5c 5、iPad Air 2 Pro、iPad mini 2 3 4、iPad 4th Gen【苹果MFi认证】(黑白)| 4.3766233766233764 |很棒的电缆并且运行良好。与 Apple 数据线完全相同。我会向任何想要省钱并寻求优质电缆的人推荐此产品。 |苹果认证的Lightning数据线| 1078 | 1078
| B004911E9M |适用于 iPhone 4、3GS 和 iPod 的壁式交流充电器 USB 同步数据线 | 2.4281805745554035 |对我来说这完全是浪费钱,因为我需要将它用于 iPhone 4。插头只能倒置插入,因此根本无法使用。 |不适用于 iPhone 4! | 731 | 731
| B002D4IHYM |新 Trent Easypak 7000mAh 便携式三 USB 端口外部电池充电器/电源组,适用于智能手机、平板电脑等(带内置 USB 线)| 4.5216095380029806 |我根据阅读的评论购买了该产品,我很高兴我这么做了。我在收到产品后确实遇到了对 itouch 充电的问题,但我给公司发了电子邮件,他们立即纠正了问题。非常好的客户服务,非常及时。产品本身非常好。它可以非常快速地为我耗电的 itouch 充电,而且 imax 电池的电量可以持续很长时间。总而言之,这是一次非常好的购买,我会推荐给所有拥有 itouch 的人。 |伟大的产品和公司| 671 | 671
+------------+------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------+--------------------+-------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------+------------------------ ----------+--------+
一组 3 行(1.54 秒)
综上所述,倒排索引可以为低基数列的查询带来 15% 的加速。所以它不仅无害,而且有利于低基数数据过滤。
此外,Apache Doris 对低基数列采用有效的字典编码和压缩。它还利用内置索引(如 ZoneMap)进行过滤。因此,即使没有倒排索引,它也能提供理想的查询性能。
结论
Apache Doris 中的倒排索引根据谓词列(SQL 查询中的 WHERE
子句)优化数据过滤。它减少了不必要的数据扫描,显着提高了高基数列的查询速度,并保证对低基数列不会产生负面影响。它支持轻量级索引管理,包括ADD/DROP INDEX和BUILD INDEX。可以通过 enable_inverted_index_query=true/false
轻松启用或禁用它。
倒排索引和NGram BloomFilter索引适用于不同的场景。您可以通过以下方式确定哪一个是最佳选择:
- 非主键列查询:这些情况通常涉及值分散且命中率较低的情况。 倒排索引可以与 Doris 中的内置智能索引结合使用,以加速这些查询。它对标量数据类型(包括字符、数字和日期时间)具有完善的支持。
- 短文本搜索:如果数据集包含高度多样化的短文本,NGram BloomFilter将是模糊搜索的有效选择短文本匹配 (
LIKE
)。如果短文本非常相似(有很多相同的内容),倒排索引会更有效,因为它可以确保更小的字典和更快的行号检索。
- 长文本搜索:倒排索引是长文本的更好选择。与野蛮的字符串匹配相比,它大大减少了CPU资源消耗。
倒排索引在Apache Doris中已经上线近一年了,经受住了众多用户在生产环境中海量数据的考验。在 Apache Doris 的未来版本中,关于倒排索引,我们计划添加对以下内容的支持:
- 自定义标记化:提供用户定义的标记器以适应不同的用例。
- 更多数据类型:用户将能够为复杂数据类型(包括数组和映射)创建倒排索引。
如果您在 Apache Doris 中尝试时遇到任何问题或想了解更多详细信息,请加入我们的 Slack 社区并与我们交谈!