You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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性能更优?


问题解答

  1. 关于yb_hash_code()的误解
    使用yb_hash_code()并不会跳过分片查找步骤,反而会引入额外的性能开销。

  2. 查询2性能更优的核心原因

    • 当直接使用item_id = any(...)时,YugabyteDB会利用主键的哈希分布特性,为每个item_id单独计算哈希值并直接定位到对应的分片,然后并行向这些分片的leader发送删除请求。这种方式不需要扫描任何分片范围,直接精准定位目标记录,执行效率极高。
    • 而查询1中添加的yb_hash_code(item_id)范围条件,会强制数据库先扫描整个[0,1395)的分片范围,之后再在扫描结果中过滤符合item_id列表的记录。这相当于多了一次全分片扫描的操作,即使目标记录都在该分片范围内,数据库也无法直接定位到具体记录,必须遍历分片内的数据再做匹配,这会带来大量不必要的IO和计算开销,导致执行时间大幅增加。
  3. 分片查找步骤的优化逻辑
    查询2的方式才是真正优化了分片查找——通过精确主键匹配直接定位到目标分片;而查询1的方式反而限制了数据库的优化能力,使其无法利用主键的精准定位特性,只能做范围扫描后再过滤。


内容的提问来源于stack exchange,提问作者dh YB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:57:18