[firebase-br] Firebird 3 Lento, usando um PLAN incorreto
Claudio
claudio em ltsinformatica.com.br
Ter Maio 10 11:25:03 -03 2016
Segue um exemplo de uma SQL na tabela TESTE_DB, no firebird 2.0 e 2.5 ele
usa o plano TESTE_DB_IDX2 que é o ideal mas no firebird 3 (3.0.1.32512) ele
usa o plano TESTE_DB_IDX1 e como minha tabela original tem muitos registro
ele fica extremamente lento.
- firebird 2.5
SELECT DOCUMENTO,SUM(PEDIDO_QUANTIDADE)
FROM TESTE_DB
WHERE (EMPRESA = '001') AND
(PEDIDO_NUMERO = 'TESTE') AND
(PEDIDO_ITEM = 1) AND
(PEDIDO_QUANTIDADE > 0)
GROUP BY 1
ORDER BY 1
Explain plan
-> Table "TESTE_DB" Access By ID
-> Index "TESTE_DB_IDX2"
- firebird 3 sem especificar o PLAN
SELECT DOCUMENTO,SUM(PEDIDO_QUANTIDADE)
FROM TESTE_DB
WHERE (EMPRESA = '001') AND
(PEDIDO_NUMERO = 'TESTE') AND
(PEDIDO_ITEM = 1) AND
(PEDIDO_QUANTIDADE > 0)
GROUP BY 1
ORDER BY 1
Explain plan
Select Expression
-> Aggregate
-> Filter
-> Table "TESTE_DB" Access By ID
-> Index "TESTE_DB_IDX1" Range Scan (partial match: 1/3)
- firebird 3 especificando o PLAN
SELECT DOCUMENTO,SUM(PEDIDO_QUANTIDADE)
FROM TESTE_DB
WHERE (EMPRESA = '001') AND
(PEDIDO_NUMERO = 'TESTE') AND
(PEDIDO_ITEM = 1) AND
(PEDIDO_QUANTIDADE > 0)
GROUP BY 1
PLAN (TESTE_DB INDEX (TESTE_DB_IDX2))
ORDER BY 1
Explain plan
Select Expression
-> Aggregate
-> Sort (record length: 108, key length: 20)
-> Filter
-> Table "TESTE_DB" Access By ID
-> Bitmap
-> Index "TESTE_DB_IDX2" Range Scan (full match)
/**************************************************************************
****/
/**** Tables
****/
/**************************************************************************
****/
CREATE TABLE TESTE_DB (
EMPRESA VARCHAR(5),
DOCUMENTO VARCHAR(15),
ITEM INTEGER,
PEDIDO_NUMERO VARCHAR(12),
PEDIDO_ITEM INTEGER,
PEDIDO_QUANTIDADE DOUBLE PRECISION);
/**************************************************************************
****/
/**** Indices
****/
/**************************************************************************
****/
CREATE UNIQUE INDEX TESTE_DB_IDX1 ON TESTE_DB (EMPRESA, DOCUMENTO, ITEM);
CREATE INDEX TESTE_DB_IDX2 ON TESTE_DB (EMPRESA, PEDIDO_NUMERO,
PEDIDO_ITEM);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0001', 1, 'TESTE', 1, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0002', 2, 'TESTE', 2, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0003', 3, 'TESTE', 3, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0004', 4, 'TESTE', 4, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0005', 5, 'TESTE', 5, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0006', 6, 'TESTE', 6, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0007', 7, 'TESTE', 7, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0008', 8, 'TESTE', 8, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0009', 9, 'TESTE', 9, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0010', 10, 'TESTE', 10, 30);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0011', 11, 'TESTE', 11, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0012', 12, 'TESTE', 12, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0013', 13, 'TESTE', 13, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0014', 14, 'TESTE', 14, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0015', 15, 'TESTE', 15, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0016', 16, 'TESTE', 16, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0018', 18, 'TESTE', 18, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0019', 19, 'TESTE', 19, 20);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0020', 20, 'TESTE', 20, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0021', 21, 'TESTE', 21, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0022', 22, 'TESTE', 22, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0023', 23, 'TESTE', 23, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0024', 24, 'TESTE', 24, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0025', 25, 'TESTE', 25, 5);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0026', 26, 'TESTE', 26, 10);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0028', 28, 'TESTE', 28, 10);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0029', 29, 'TESTE', 29, 10);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0032', 32, 'TESTE', 32, 10);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0034', 34, 'TESTE', 34, 10);
INSERT INTO TESTE_DB (EMPRESA, DOCUMENTO, ITEM, PEDIDO_NUMERO, PEDIDO_ITEM,
PEDIDO_QUANTIDADE)
VALUES ('001', '201502.0035', 35, 'TESTE', 35, 10);
COMMIT WORK;
Mais detalhes sobre a lista de discussão lista