Sibumulação de XOR (exclusive or) no Firebird

Firebird

18/09/2013

Tentei simular um XOR no firebird já que não encontrei nada do tipo na documentação.

Tenho uma QUERY simples mas o firebird se recusa a usar o índice que eu criei onde se o parametro do código do cliente for igual a -1 seleciona para todos os clientes mas se for diferente de um então retorna somente o daquele código informado:

SELECT
        F.CODCLI as CODIGO,
        C.NOME AS NOME,
        F.CREDITO AS VALOR,
        IIF(F.BAIXADO='S',F.CREDITO,0) AS VALOR_BAIXADO,
        IIF(F.BAIXADO='N',F.CREDITO,0) AS VALOR_NBAIXADO,
        F.BAIXADO
    FROM
        FIN_CREDCLIE F
        INNER JOIN CLIENTES C ON
        (
            C.CODIGO = F.CODCLI
        )
    WHERE
        ((:CODIGO <> -1 AND F.CODCLI = :CODIGO) or (:codigo = -1 and F.CODCLI is distinct from -1))


o problema é que não usa o indice:

Plan
PLAN JOIN (F NATURAL, C INDEX (PK_CLIENTES))

------ Performance info ------
Prepare time = 0ms
Execute time = 187ms
Avg fetch time = 62,33 ms
Current memory = 966.112
Max memory = 14.509.604
Memory buffers = 90
Reads from disk to cache = 4.100
Writes from cache to disk = 0
Fetches from cache = 442.431


Porém a Mesma QUERY com com a clausula where puxando o código de forma direta utiliza o índice:

SELECT
        F.CODCLI as CODIGO,
        C.NOME AS NOME,
        F.CREDITO AS VALOR,
        IIF(F.BAIXADO='S',F.CREDITO,0) AS VALOR_BAIXADO,
        IIF(F.BAIXADO='N',F.CREDITO,0) AS VALOR_NBAIXADO,
        F.BAIXADO
    FROM
        FIN_CREDCLIE F
        INNER JOIN CLIENTES C ON
        (
            C.CODIGO  = F.CODCLI and
            c.EMPRESA = f.EMPRESA
        )
    WHERE
        F.CODCLI = :codigo




Plan
PLAN JOIN (F INDEX (FIN_CREDCLIE_IDX2), C INDEX (PK_CLIENTES))

------ Performance info ------
Prepare time = 16ms
Execute time = 0ms
Avg fetch time = 0,00 ms
Current memory = 962.660
Max memory = 14.509.604
Memory buffers = 90
Reads from disk to cache = 4
Writes from cache to disk = 0
Fetches from cache = 33


Prodados Ltda

Prodados Ltda

Curtidas 0

Respostas

Prodados Ltda

Prodados Ltda

18/09/2013

Só para Acrescentar, a query funciona como esperado, somente não usa o índice criado:

Segue o Código de criação das tabelas para quem quiser experimentar:

CREATE TABLE CLIENTES (
    EMPRESA         SIGLA_EMPRESA NOT NULL /* SIGLA_EMPRESA = CHAR(3) NOT NULL */,
    CODIGO          INTEGER NOT NULL,
    NOME            VARCHAR(50),
    CONTATO         VARCHAR(30),
    ENDERECO        VARCHAR(50),
    BAIRRO          VARCHAR(40),
    CIDADE          VARCHAR(30),
    UF              CHAR(2),
    CEP             CHAR(8),
    TELEFONE        VARCHAR(10),
    FAX             VARCHAR(10),
    CNPJ            VARCHAR(14),
    CPF             VARCHAR(11),
    INSC_ESTADUAL   VARCHAR(20),
    INSC_MUNICIPAL  VARCHAR(20),
    LOCAL_COBRANCA  VARCHAR(50),
    OUTRAS_INF      BLOB SUB_TYPE 0 SEGMENT SIZE 100,
     COD_CIDADE      INTEGER,
    COD_PAIS        COD_PAIS /* COD_PAIS = VARCHAR(6) */,
    NUMERO          VARCHAR(10),
    COMPLEMENTO     VARCHAR(30),
    EMAIL           VARCHAR(80),
    INSC_RURAL      TEXTO_16 /* TEXTO_16 = VARCHAR(16) */
);

ALTER TABLE CLIENTES ADD CONSTRAINT PK_CLIENTES PRIMARY KEY (EMPRESA, CODIGO);

CREATE INDEX CLIENTES_IDX2 ON CLIENTES (CNPJ);
CREATE INDEX CLIENTES_IDX3 ON CLIENTES (CPF);

/***********************************************************************************************************/

CREATE TABLE FIN_CREDCLIE (
    CREDCLI_ID    INTEGER NOT NULL,
    EMPRESA       CHAR(3) NOT NULL,
    CODCLI        INTEGER NOT NULL,
    DATACRE       DATE NOT NULL,
    CREDITO       NUMERIC(13,2),
    OBS           VARCHAR(50),
    BAIXADO       BOOLEAM /* BOOLEAM = CHAR(1) */,
    BAIXADO_DATA  DATA /* DATA = DATE */
);

ALTER TABLE FIN_CREDCLIE ADD CONSTRAINT PK_FIN_CREDCLIE PRIMARY KEY (CREDCLI_ID);

CREATE INDEX FIN_CREDCLIE_IDX1 ON FIN_CREDCLIE (CODCLI);
CREATE INDEX FIN_CREDCLIE_IDX2 ON FIN_CREDCLIE (CODCLI, DATACRE);
CREATE INDEX FIN_CREDCLIE_IDX3 ON FIN_CREDCLIE (CREDCLI_ID, DATACRE, BAIXADO);


GOSTEI 0
Prodados Ltda

Prodados Ltda

18/09/2013

Alguem tem alguma idéia de como resolver isto?
GOSTEI 0
POSTAR