YugabyteDB中含yb_hash_code()的DELETE查询性能为何下降?
YugabyteDB DELETE查询性能差异疑问
问题背景
给定表结构:
CREATE TABLE IF NOT EXISTS public.item_data ( item_id uuid NOT NULL, id2 integer NOT NULL, create_date timestamp without time zone NOT NULL, modified_date timestamp without time zone NOT NULL, CONSTRAINT item_data_pkey PRIMARY KEY (item_id, id2) );
YugabyteDB集群包含48个tablet,第一个哈希范围为[0, 1395)。两种DELETE查询的执行时间差异显著:
查询1(使用
yb_hash_code())EXPLAIN ANALYZE DELETE FROM item_data x WHERE yb_hash_code(x.item_id)>=0 and yb_hash_code(x.item_id)<1395 and x.item_id = any(arrayOfItemIds);执行耗时:2秒
查询2
EXPLAIN ANALYZE DELETE FROM item_data x WHERE x.item_id = any(listOfItemIds);执行耗时:2毫秒
用户对DELETE的执行流程理解为:1. 根据WHERE子句查找分片;2. 在分片leader上执行查询;3. 在分片follower上复制变更;4. 向客户端响应。
用户疑问:WHERE子句中使用yb_hash_code()应该能跳过步骤1,这是否正确?为何查询2比查询1性能更优?
问题解答
关于
yb_hash_code()的误解
使用yb_hash_code()并不会跳过分片查找步骤,反而会引入额外的性能开销。查询2性能更优的核心原因
- 当直接使用
item_id = any(...)时,YugabyteDB会利用主键的哈希分布特性,为每个item_id单独计算哈希值并直接定位到对应的分片,然后并行向这些分片的leader发送删除请求。这种方式不需要扫描任何分片范围,直接精准定位目标记录,执行效率极高。 - 而查询1中添加的
yb_hash_code(item_id)范围条件,会强制数据库先扫描整个[0,1395)的分片范围,之后再在扫描结果中过滤符合item_id列表的记录。这相当于多了一次全分片扫描的操作,即使目标记录都在该分片范围内,数据库也无法直接定位到具体记录,必须遍历分片内的数据再做匹配,这会带来大量不必要的IO和计算开销,导致执行时间大幅增加。
- 当直接使用
分片查找步骤的优化逻辑
查询2的方式才是真正优化了分片查找——通过精确主键匹配直接定位到目标分片;而查询1的方式反而限制了数据库的优化能力,使其无法利用主键的精准定位特性,只能做范围扫描后再过滤。
内容的提问来源于stack exchange,提问作者dh YB
相关产品推荐
相关产品推荐

