为什么会发生错误8349?虽然索引包括了一个Varchar(2000)类型的字段,但数据的长度并没有超过1024字节,怎样解决这个问题呢?(From DBMR1811)

~ 0 min
2016-02-24 04:56

(1). 首先,当创建一个包含varchar类型字段的索引时,DBMaster不会检查出索引的长度。

例如:

dmSQL> create table dbmr1811(id  SERIAL(1),application_name  VARCHAR(2000) default null );

dmSQL> create index idx_dbmr1811 on dbmr1811 (application_name);

以上的idx_dbmr1811包含了一个长度超过1024的varchar(2000)字段,但是能够成功创建索引,原因是DBMaster直到使用这个索引时,才检验它的长度。

(2). 当使用以上的索引时,DBMaster将根据不同的执行计划检验部分索引的长度。当一个执行计划使用嵌套连接时,它不知道这个数据的长度,所以它将会使用varchar类型的定义长度(在此处为2000字节)作为数据长度来分配缓存。当检验长度时,如果发现索引长度1024字节时,就会返回错误8394。

例如:

dmSQL> create table c1(a1  VARCHAR(2000) default null );

dmSQL> create  index idx_c1 on c1 ( a1 );

dmSQL> create table d1(a1  VARCHAR(2000) default null );

dmSQL> create  index idx_d1 on d1 ( a1 );

dmSQL> select * from c1 JOIN d1 on c1.a1 = d1.a1 where 1=1;

ERROR (8349): [DBMaster] total length of index key exceeds maximum length (1024 Bytes)

(3).有两种方法可以避免这种情况。

一种是执行“update statistics”。在执行“update statistics”之后,执行计划使用合并连接并且varchar的长度是实际长度并非定义的长度。

另一个方法是在表中使用强制合并连接。DBMaster4.3提供了强制优化的语法;你可以使用“MERGE JOIN…”语法让查询运行,然后使用“MERGE JOIN…”,并非Nested JOIN进行。

例如:

dmSQL> select * from c1 MERGE JOIN  d1 on c1.a1 = d1.a1 where 1=1;

(4). 请注意,尽管成功地创建了这个类型索引(包括varchar类型字段),但插入的数据不能超过1024字节。

(5). 您最好不要在长字段建立普通索引。这种类型的索引将占用过多的索引页并且查询时有可能不被使用。所以我们建议用户在长字段创建全文索引。

平均分: 0 (0 投票)

你不能对该内容发表评论

标签