Fórum Sibumulação de XOR (exclusive or) no Firebird #455780
18/09/2013
0
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:
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:
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
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
Curtir tópico
+ 0
Responder
Posts
18/09/2013
Prodados Ltda
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:
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);
Responder
Gostei + 0
31/12/2013
Prodados Ltda
Alguem tem alguma idéia de como resolver isto?
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)