为长列创建索引

dma*_*a_k 3 db2

我正在寻找在长列上创建索引的替代方法:

create table line
(
    field_key   integer not null,
    value       varchar(4000),
    ...
);

create index key_value_idx on line (field_key, value);
Run Code Online (Sandbox Code Playgroud)

结果DB2 SQL Error: SQLCODE=-614, SQLSTATE=54008。文档说:The sum of the stored lengths of the specified columns must not be greater than 1024。对于 MySQL 中的这种情况,有语法

create index key_value_idx on line (field_key, value(1000));
Run Code Online (Sandbox Code Playgroud)

和 HSQLDB 只是没有任何限制地工作。

DB2 的类似物是什么?

Chr*_*ich 6

以下是有关DB2的CREATE INDEX语句的信息。您可能还想查看有关设计索引索引空间要求的这些链接,因为它们还处理您关于哪些因素影响索引页面空间的问题。

根据最后一个链接,在我看来,索引的页面大小将是您的列长度 + 索引开销。这可能会使您超出表格的页面大小。(也许这就是这里发生的事情。)您也可以尝试将您的表放在更大的表空间中。它也可以将索引放在更大的页面大小中。

编辑:我也在本地测试过这个。使用控制中心,我能够更详细地了解错误消息。每个 DB2:“说明:

无法创建或更改索引,因为键列内部长度的总和将超过索引键长度限制。此外,不能使用 LONG VARCHAR、LONG VARGRAPHIC 或 LOB 列创建索引。如果索引是在类型表上定义的,则存在额外的索引开销,将最大长度减少 4 个字节。该索引可能会被 ALTER TABLE 或 ALTER NICKNAME 语句更改,这些语句会更改一个或多个列的数据类型。

无法创建索引扩展,因为 GENERATE KEY 函数返回的列总和将超过索引键长度限制。

索引键长度限制基于索引使用的表空间的页面大小:

Max Key Length  Page size
--------------  ---------
1K              4K
2K              8K
4K              16K
8K              32K
Run Code Online (Sandbox Code Playgroud)

无法处理该语句。未创建指定的索引或索引扩展,或者无法更改表或昵称。

用户回复:

要修改索引定义或更改列,请删除一个或多个键列并将键长度减少到允许的最大值。对于索引扩展定义,请指定不同的 GENERATE KEY 函数,或重新定义该函数以减少返回行的长度。”

正如我在下面的评论中提到的,您的密钥大小至少为 32 +(4000 * 2(对于 UTF-16))+ 2(对于 varchar 长度标识符)+ 索引开销,因此您已经达到 8034+ 字节。这意味着刚刚超过 7K。我猜你没有定义表空间,所以它会默认为 USERSPACE1,这是一个 8K 表空间),所以你有一个 2K 最大密钥长度,如上表所示,加上你的错误消息)。为了制作这个钥匙,你必须做两件事之一

  1. 更改您的表定义,使其不会太大(可能会减少您的 varchar 大小),以便您可以适应 1K 最大键定义。我猜你不想这样做,所以你结束做下一个:

  2. 由于您的密钥空间需要 8K 的密钥长度,因此您需要 32K 的页面大小。您可以将表保留在默认的 4K 表空间中,但索引必须位于 32K 表空间中。如果您使用自动存储,您可以使用以下内容轻松创建表空间:

create bufferpool BP32K immediate size 250 automatic pagesize 32K;
create large tablespace TS32K pagesize 32K managed by automatic
storage bufferpool BP32K; 
create table line (
  field_key   integer not null,
  value       varchar(4000),
  ... ) index in TS32K; 
create index key_value_idx on line (field_key, value);
Run Code Online (Sandbox Code Playgroud)

这会将索引放在 32K 表空间中,您应该没问题。


And*_*mar 5

如果您打算使用索引进行相等,您可以添加一个校验和计算列:

alter table line add value_checksum as checksum(value)
create index IX_LINE_VALUE_CHECKSUM on line(value_checksum)
Run Code Online (Sandbox Code Playgroud)

然后你可以选择像:

select * from line where checksum_value = checksum('search text here')
Run Code Online (Sandbox Code Playgroud)