CREATE TABLE IF NOT EXISTS events
(
id UUID NOT NULL,
type_id UUID,
occurred_at TIMESTAMP WITH TIME ZONE NOT NULL,
PRIMARY KEY (id)
);
乔德代码:
val queryDsl = dslContext.select(EventFields).from(EVENTS)
.where(
(EVENTS.TYPE_ID.isNull)
.or(EVENTS.TYPE_ID.eq(query.typeId.id))
)
型号识别码:
import java.util.UUID
data class TypeId(val id: UUID) {
constructor (id: String) : this(UUID.fromString(id))
override fun toString(): String = id.toString()
}
查询:
where ("public"."events"."type_id" = cast('d0c6a2a7-2032-4dd7-b2b1-77a554262af7' as uuid))
为什么要投?
我试图摆脱这种转换,因为它影响我的索引表现
我的索引:CREATE INDEX company_employee_occurred_at_idx ONbalance_state_event(id,type_id,occurred_at DESC);
在我的解释查询中,其中一行是: Filter: ((type_id IS NULL) OR (type_id = '390caffd-9c3b-4ea4-b5e2-6ae342268141'::uuid)),为什么有一个显式过滤器,如果索引在吗
为什么要投?
jOOQ 中有一个相对较新的修复,其中 all
UUID
绑定值现在显式转换为其类型:
3.20.0
SQLDialect.POSTGRES
类型化绑定值,就像它自动转换所有这些类型化绑定值一样:
这回答了您提出的问题(标题中的问题)。
我试图摆脱这种转换,因为它影响我的索引表现
我不认为这个演员阵容会影响你的表演。绑定值是一个常量,转换它不会改变任何东西。如果没有强制转换,随着类型的提升,仍然会存在隐式强制转换。
但是,您的
UUID
谓词更有可能出现问题:
OR
请检查为什么在您的情况下,执行计划中没有出现
((type_id IS NULL) OR (type_id = '390caffd-9c3b-4ea4-b5e2-6ae342268141'::uuid))
操作。从你提供的很少的信息来看,很难说。在一个更简单的例子中,这工作得很好:
BitmapOr
制作:
create table t (i uuid);
create index i on t (i);
insert into t select uuid_generate_v4() from generate_series(1, 1000000) as t (i);
explain
select *
from t
where i is null or i = cast('390caffd-9c3b-4ea4-b5e2-6ae342268141' as uuid)
这表明您可能还有另一个问题要问,最好是一个新问题,因为这个问题是关于 jOOQ 和选角,而不是关于您的实际性能问题。