2017-01-24 19 views
2

Firebird позволяет indexing on expressions начиная с версии 2.0 . Это включает в себя использование вызовов пользовательских функций (UDF).размер ключа превышает ограничение для реализации индекса на экспрессию с UDF вызова

В настоящее время я пытаюсь добавить индекс выражения в эту таблицу:

CREATE TABLE M_ADSN_STRING_DATA (
    ID    DMN_AUTOINC NOT NULL /* DMN_AUTOINC = INTEGER NOT NULL */, 
    CLTREF   DMN_REFID /* DMN_REFID = INTEGER NOT NULL */, 
    ATTRIBUTEDATA DMN_AFT_STRING /* DMN_AFT_STRING = VARCHAR(320) NOT NULL */ 
); 

/******************************************************************************/ 
/****       Unique constraints       ****/ 
/******************************************************************************/ 

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT UNQ_M_ADSN_STRING_DATA UNIQUE (CLTREF, ATTRIBUTEDATA); 


/******************************************************************************/ 
/****        Primary keys        ****/ 
/******************************************************************************/ 

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT PK_M_ADSN_STRING_DATA PRIMARY KEY (ID); 


/******************************************************************************/ 
/****        Foreign keys        ****/ 
/******************************************************************************/ 

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT FK_M_ADSN_STRING_DATA_CLT FOREIGN KEY (CLTREF) REFERENCES M_CLIENT (ID) ON DELETE CASCADE ON UPDATE CASCADE; 


/******************************************************************************/ 
/****        Indices        ****/ 
/******************************************************************************/ 

CREATE INDEX M_ADSN_STRING_DATA_AD_UC ON M_ADSN_STRING_DATA COMPUTED BY (UPPER(ATTRIBUTEDATA)); 

Обратите внимание, что он уже имеет индекс выражения называется M_ADSN_STRING_DATA_AD_UC.

Индекс Я хочу использовать должен выглядеть следующим образом:

CREATE INDEX M_ADSN_STRING_DATA_AD_DIG 
    ON M_ADSN_STRING_DATA 
    COMPUTED BY (F_DIGITS(ATTRIBUTEDATA)); 

К сожалению, это дает мне сообщение об ошибке.

Неудачное обновление метаданных размер ключа превышает ограничение реализации для индекса "M_ADSN_STRING_DATA_AD_DIG"

Я прочитал Firebird FAQ entrys #213 и #211, и это SO question, а также. F_DIGITS является UDF Библиотека FreeAdhocUDF. Первоначально он был объявлен как

DECLARE EXTERNAL FUNCTION F_DIGITS 
     CSTRING(32760) 
RETURNS CSTRING(32760) FREE_IT 
ENTRY_POINT 'digits' MODULE_NAME 'FreeAdhocUDF'; 

Как мой максимальный входной и выходной длина составляет всего 320 символов, я изменил его на

DECLARE EXTERNAL FUNCTION F_DIGITS 
    CSTRING(320) 
RETURNS CSTRING(320) FREE_IT 
ENTRY_POINT 'digits' MODULE_NAME 'FreeAdhocUDF'; 

, чтобы соответствовать требованиям к размеру индекса. Мои базы данных - 16384. Итак, я думаю, мой ключ может быть до 4096 байт.

домен DMN_AFT_STRING колонны ATTRIBUTEDATA объявлен

CREATE DOMAIN DMN_AFT_STRING AS 
VARCHAR(320) CHARACTER SET ISO8859_1 
NOT NULL 
COLLATE DE_DE_CS_SF; 

Почему размер ключа превышает?

ответ

1

Краткая история: вы пытались выключить и снова включить?

После изменения декларации UDF и перед добавлением индекса выражения, необходимо, чтобы отсоединил и соединил.

Теперь он работает правильно. Размер ключа больше не превышает.

+0

yep, кэш метаданных иногда связан с транзакциями, а иногда нет, а также отличается между суперсервером и классическим. Как только вы вызвали эту функцию, она получила «разогрев». Однако ... Вы уверены, что ваши изменения приемлемы? вы нарезали буфер памяти функции без фактического изменения ее реализации. Интересно ... Может быть, я попытаюсь установить индекс в 'cast (myfunction (x) как VarChar (320))' явно обрезает буфер в области SQL, а не на границе SQL/двоичный. –

+0

Я думаю, что все в порядке. Я знаю, как реализуется UDF. Он полностью независим с точки зрения длины ввода и вывода. –