如何在informix索引中使用NVL2函数

时间:2014-03-19 08:41:34

标签: informix

我想使用NVL2函数创建索引:

create index i_name on PERSON (
   NVL2(date1,date2,date3)
);

此打印错误:

Routine (nvl2) can not be resolved.

我想念的是什么?为什么这不起作用

1 个答案:

答案 0 :(得分:2)

NVL2的使用不可用,因为功能索引不接受内置函数。以下是在Informix中使用功能索引的基本规则(v12.10): (quoted from the manual

  

重要说明:数据库服务器对以下内容施加了以下限制   功能索引所在的用户定义例程(UDR)   定义:

     
      
  • 参数不能是集合数据类型的列值。
  •   
  • 该函数无法返回大对象(包括内置类型BLOB,BYTE,CLOB和TEXT)。
  •   
  • 该功能不能是VARIANT功能。
  •   
  • 该函数不能包含任何SQL的DML语句。
  •   
  • 该功能必须是UDR,而不是内置功能。但是,您可以创建一个调用并返回的SPL包装器   来自SQL的内置函数的值。
  •   

我在这里复制一个有效的例子,你可以在你的环境中运行以进行测试 也许需要一些调整,因为我在版本11.70运行它并设置我自己的dbspaces ....

$ cat test.sql
database sysutils;

-- showing my version of informix...
select dbinfo('version','full') from sysmaster:sysdual;

-- creating a database for this test
drop database if exists teste  ;
create database teste in dbadat1dbs with buffered log;

-- registering excompat datablate just to enable the use of the dbms_random function for this example.
execute function sysbldprepare('excompat.1.0', 'create');

-- create my test table
drop table if exists mytables;
create table if not exists mytables ( id int, name char(20), created date, modified date, invalidated date) ;

-- including some records...
insert into mytables(id,name,created) select tabid, tabname , created from sysmaster:systables;

-- creating some random data for this example
update mytables set modified = dbinfo('utc_to_datetime',dbms_random_random()) where name matches '*[xmfz]*';
update mytables set invalidated = dbinfo('utc_to_datetime',dbms_random_random()) where modified is not null;


-- trying use the nvl2... which is not possible because it is a builtin function
create index i1_mytables on mytables ( nvl2(modified, created, invalidated)) ;

-- creating my own function, non variant mode.
drop function if exists my_nvl2_date;
create function if not exists  my_nvl2_date (  dt date , is_null date, not_null date )
  returning date
with (not variant)
return nvl2(dt, is_null, not_null) ;
end function
;

-- create the index
create index i1_mytables on mytables ( my_nvl2_date(modified, created, invalidated)) ;

set explain file to 'test.out' ;
select first 20 * from mytables;
-- here, the index will be used
select first 20 * from mytables where my_nvl2_date(modified, created, invalidated) >= '01/01/2000';
-- this will not use the index because don't match exactly the parameters
select first 20 * from mytables where my_nvl2_date(modified, invalidated, created) >= '01/01/2000';

这是执行。 注意解释文件,在使用索引时显示,而不是。

$ dbaccess -e - test.sql
database sysutils;
Database selected.



-- showing my version of informix...
select dbinfo('version','full') from sysmaster:sysdual;

(constant)

IBM Informix Dynamic Server Version 11.70.FC6

1 row(s) retrieved.



-- creating a database for this test
drop database if exists teste  ;
Database dropped.


create database teste in dbadat1dbs with buffered log;
Database closed.


Database created.



-- registering excompat datablate just to enable the use of the dbms_random function for this example.
execute function sysbldprepare('excompat.1.0', 'create');

(expression)

           0

1 row(s) retrieved.



-- create my test table
drop table if exists mytables;
Table dropped.


create table if not exists mytables ( id int, name char(20), created date, modified date, invalidated date) ;
Table created.



-- including some records...
insert into mytables(id,name,created) select tabid, tabname , created from sysmaster:systables;
276 row(s) inserted.



-- creating some random data for this example
update mytables set modified = dbinfo('utc_to_datetime',dbms_random_random()) where name matches '*[xmfz]*';
113 row(s) updated.


update mytables set invalidated = dbinfo('utc_to_datetime',dbms_random_random()) where modified is not null;
113 row(s) updated.




-- trying use the nvl2... which is not possible because it is a builtin function
create index i1_mytables on mytables ( nvl2(modified, created, invalidated)) ;
  674: Routine (nvl2) can not be resolved.
Error in line 26
Near character position 75


-- creating my own function, non variant mode.
drop function if exists my_nvl2_date;
Routine dropped.


create function if not exists  my_nvl2_date (  dt date , is_null date, not_null date )
  returning date
with (not variant)
return nvl2(dt, is_null, not_null) ;;
end function
;
Routine created.

;

-- create the index
create index i1_mytables on mytables ( my_nvl2_date(modified, created, invalidated)) ;
Index created.



set explain file to 'test.out' ;
Explain set.


select first 20 * from mytables;

         id name                 created    modified   invalidated

          1 systables            05/06/2013
          2 syscolumns           05/06/2013 22/10/1942 13/04/2034
          3 sysindices           05/06/2013
          4 systabauth           05/06/2013
          5 syscolauth           05/06/2013
          6 sysviews             05/06/2013
          7 sysusers             05/06/2013
          8 sysdepend            05/06/2013
          9 syssynonyms          05/06/2013 15/03/1981 19/05/1963
         10 syssyntable          05/06/2013
         11 sysconstraints       05/06/2013
         12 sysreferences        05/06/2013 15/08/1912 09/06/1956
         13 syschecks            05/06/2013
         14 sysdefaults          05/06/2013 09/01/1959 01/03/1943
         15 syscoldepend         05/06/2013
         16 sysprocedures        05/06/2013
         17 sysprocbody          05/06/2013
         18 sysprocplan          05/06/2013
         19 sysprocauth          05/06/2013
         20 sysblobs             05/06/2013

20 row(s) retrieved.


-- here, the index will be used
select first 20 * from mytables where my_nvl2_date(modified, created, invalidated) >= '01/01/2000';

         id name                 created    modified   invalidated

          2 syscolumns           05/06/2013 22/10/1942 13/04/2034
          9 syssynonyms          05/06/2013 15/03/1981 19/05/1963
         12 sysreferences        05/06/2013 15/08/1912 09/06/1956
         14 sysdefaults          05/06/2013 09/01/1959 01/03/1943
         25 sysfragments         05/06/2013 29/10/1951 11/02/1953
         28 sysfragauth          05/06/2013 06/12/2024 03/11/1948
         30 sysxtdtypes          05/06/2013 20/03/1909 03/05/1975
         32 sysxtddesc           05/06/2013 23/04/1933 23/07/1961
         35 syslogmap            05/06/2013 01/03/2015 30/05/2020
         37 sysxtdtypeauth       05/06/2013 16/03/1911 26/12/2037
         40 sysams               05/06/2013 02/06/1940 19/08/2000
         41 systabamdata         05/06/2013 21/04/2032 17/02/1907
         45 systracemsgs         05/06/2013 14/04/2006 09/11/1936
         49 sysxasourcetypes     05/06/2013 03/04/1994 28/05/1972
         50 sysxadatasources     05/06/2013 09/09/1967 29/11/1978
         51 sysseclabelcomponent 05/06/2013 26/04/1979 21/09/1984
         52 sysseclabelcomponent 05/06/2013 10/10/2035 16/06/2021
         54 syssecpolicycomponen 05/06/2013 23/08/1962 20/05/1983
         55 syssecpolicyexemptio 05/06/2013 09/01/1966 04/12/2027
         57 sysseclabelnames     05/06/2013 09/03/1948 03/09/1937

20 row(s) retrieved.


-- this will not use the index because don't match exactly the parameters
select first 20 * from mytables where my_nvl2_date(modified, invalidated, created) >= '01/01/2000';

         id name                 created    modified   invalidated

          1 systables            05/06/2013
          2 syscolumns           05/06/2013 22/10/1942 13/04/2034
          3 sysindices           05/06/2013
          4 systabauth           05/06/2013
          5 syscolauth           05/06/2013
          6 sysviews             05/06/2013
          7 sysusers             05/06/2013
          8 sysdepend            05/06/2013
         10 syssyntable          05/06/2013
         11 sysconstraints       05/06/2013
         13 syschecks            05/06/2013
         15 syscoldepend         05/06/2013
         16 sysprocedures        05/06/2013
         17 sysprocbody          05/06/2013
         18 sysprocplan          05/06/2013
         19 sysprocauth          05/06/2013
         20 sysblobs             05/06/2013
         21 sysopclstr           05/06/2013
         22 systriggers          05/06/2013
         23 systrigbody          05/06/2013

20 row(s) retrieved.
Database closed.

这是解释文件,执行了3个选择。 仅观察使用索引的第二个选择。

$ cat test.out

QUERY: (OPTIMIZATION TIMESTAMP: 03-21-2014 21:43:22)
------
select first 20 * from mytables

Estimated Cost: 0
Estimated # of Rows Returned: 276

  1) informix.mytables: SEQUENTIAL SCAN


Query statistics:
-----------------

The final cost of the plan is reduced because of the FIRST n specification in
 the query.

  Table map :
  ----------------------------
  Internal name     Table name
  ----------------------------
  t1                mytables

  type     table  rows_prod  est_rows  rows_scan  time       est_cost
  -------------------------------------------------------------------
  scan     t1     20         276       38         00:00.00   1


QUERY: (OPTIMIZATION TIMESTAMP: 03-21-2014 21:43:22)
------
select first 20 * from mytables where my_nvl2_date(modified, created, invalidated) >= '01/01/2000'

Estimated Cost: 1
Estimated # of Rows Returned: 92

  1) informix.mytables: INDEX PATH

    (1) Index Name: informix.i1_mytables
        Index Keys: informix.my_nvl2_date(modified,created,invalidated)   (Serial, fragments: ALL)
        Lower Index Filter: informix.my_nvl2_date(informix.mytables.modified ,informix.mytables.created ,informix.mytables.invalidated )>= 01/01/2000

UDRs in query:
--------------
    UDR id  :   540
    UDR name:   my_nvl2_date
    UDR id  :   540
    UDR name:   my_nvl2_date

Query statistics:
-----------------

The final cost of the plan is reduced because of the FIRST n specification in
 the query.

  Table map :
  ----------------------------
  Internal name     Table name
  ----------------------------
  t1                mytables

  type     table  rows_prod  est_rows  rows_scan  time       est_cost
  -------------------------------------------------------------------
  scan     t1     20         92        20         00:00.00   1


QUERY: (OPTIMIZATION TIMESTAMP: 03-21-2014 21:43:22)
------
select first 20 * from mytables where my_nvl2_date(modified, invalidated, created) >= '01/01/2000'

Estimated Cost: 2
Estimated # of Rows Returned: 92

  1) informix.mytables: SEQUENTIAL SCAN

        Filters: informix.my_nvl2_date(informix.mytables.modified ,informix.mytables.invalidated ,informix.mytables.created )>= 01/01/2000

UDRs in query:
--------------
    UDR id  :   540
    UDR name:   my_nvl2_date

Query statistics:
-----------------

The final cost of the plan is reduced because of the FIRST n specification in
 the query.

  Table map :
  ----------------------------
  Internal name     Table name
  ----------------------------
  t1                mytables

  type     table  rows_prod  est_rows  rows_scan  time       est_cost
  -------------------------------------------------------------------
  scan     t1     20         92        38         00:00.00   3