将 LIKE 与 Oracle 中的 GUID 列索引一起使用

Using LIKE with index over GUID columns in Oracle

我正在构建系统,其中我决定使用 GUID 作为许多表中的主键。我做出这个决定是为了能够开发用于集成测试的工具。如果我在某些场合生成了一次主键,我可以肯定我永远不会偶然生成相同的 GUID,这意味着我可以确定我为某些测试用例准备的数据将是唯一的并且可以轻松转移到任何其他数据库,因为它在那里也是唯一的。 所以我使用我的主键 RAW(16) 数据类型。

CREATE TABLE "VMCRM"."THO_USERS" (
  "VMUSERGUID" RAW(16),
  "STATUS" VARCHAR2(2 BYTE),
  "EMAIL" VARCHAR2(255 BYTE),
  "TEL" VARCHAR2(50 BYTE)
);
CREATE UNIQUE INDEX "VMCRM"."THO_USER_PK" ON "VMCRM"."THO_USERS" ("VMUSERGUID") ;
ALTER TABLE "VMCRM"."THO_USERS" MODIFY ("VMUSERGUID" NOT NULL ENABLE);

我现在面临的问题是,我想为我的员工准备功能,允许他们通过 GUID 过滤例如应用程序的用户。在大多数情况下,他们在字段中输入 GUID 的前 8 个字符会很有效——这在大多数情况下足以找到确切的用户。然而,我正在努力使用 Oracle 索引引擎。我需要执行以下查询并期望它会使用我在列上的索引。但这并没有发生。

select * from tho_users where vmuserguid like '0001EF16%' 

查询运行良好,除了没有使用索引 - 执行了全扫描。

有人知道如何在 RAW(16) 列的此类查询中使用索引吗?

您正在将原始值与字符串进行比较,这会导致隐式转换。这可以防止您的索引被用于您的查询 - 数据类型不再适用。

您可以添加一个 function-based 使用原始值的字符串表示的索引:

create index ix_guid_2 on tho_users(rawtohex(vmuserguid));

db<>fiddle

这可能仍然是唯一的,但不能真正用于 PK 本身 - 它需要作为一个额外的索引。 This db<>fiddle除了原始值是真实的PK外,其他都是一样的。

LIKE 比较字符串,因此如果您将 non-string 值与字符串进行比较,您将强制进行隐式转换,这会阻止使用原始索引。 function-based 索引正在为该转换后的值创建索引,可以使用。