Buenos dias, tardes o noches segun corresponda. Tengo una duda que espero puedan ayudarme a despejar.
Tengo un sistema funcionando en firebird 2.5. En este tengo un listado de resumen. La consulta que lanzo es la siguiente:
Código SQL
[-]SELECT MC.ID_MOV, DC.ID_DETCIL, MC.FECHADOC, DC.CIL,CI.TIPOGASID, TG.TIPOGAS,
CI.DESCRIPCION,CI.CAPACIDAD, MC.SERIE, MC.DOCUMENTO,DC.PLAZO,
DC.FECHADEV, DC.DOCDEV,MC.NOMDESTINO, CP1.NOMBRE,CP2.ID_CLIENTE,
CP2.TIPO, CP2.NOMBRE,DC.LUGAR, DC.OBSERVACION FROM
DETALLECIL DC INNER JOIN MOVCILINDROS MC ON DC.MOVCIL=MC.ID_MOV
INNER JOIN CILINDROS CI on DC.CIL=CI.ID_CILINDRO INNER JOIN
CLIEPROV CP1 ON MC.NOMDESTINO=CP1.ID_CLIENTE INNER JOIN
CLIEPROV CP2 ON CI.PROPIETARIO=CP2.ID_CLIENTE
INNER JOIN TIPOGASES TG ON CI.tipogasid=TG.id
WHERE CP1.id_cliente>0
La consulta en si me da los resultados esperados con una demora maxima de un par de segundos. Ahora revisando en los foros escuche mencionar el IB plan analizer para analizar las consultas. Lo probe y me salio en las tablaS MOVCILINDROS Y DETALLECIL una advertencia. Revisando veo que utiliza los indices que corresponde a sus respectivas claves foraneas.
Este es el plan usado:
Código SQL
[-]PLAN JOIN (CP1 INDEX (RDB$PRIMARY2), MC INDEX (RDB$FOREIGN5), DC INDEX (RDB$FOREIGN12), CI INDEX (RDB$PRIMARY1), CP2 INDEX (RDB$PRIMARY2), TG INDEX (PK_TIPOGASES))
Estas son las tablas usadas:
Código SQL
[-]CREATE TABLE CILINDROS (
ID_CILINDRO INTEGER NOT NULL,
DESCRIPCION VARCHAR(30),
TIPOGASID INTEGER NOT NULL,
CAPACIDAD VARCHAR(7),
PROPIETARIO INTEGER,
OBSCILINDRO VARCHAR(30)
);
CREATE TABLE CLIEPROV (
ID_CLIENTE INTEGER NOT NULL,
RUC VARCHAR(11),
NOMBRE TCADENA NOT NULL COLLATE ES_ES_CI_AI,
EMAIL VARCHAR(30),
WEB VARCHAR(30),
CONTACTO VARCHAR(50),
TIPO INTEGER NOT NULL,
NOMMAYUS TCADENA COLLATE ES_ES_CI_AI,
RUBRO TRUBRO NOT NULL
);
CREATE TABLE DETALLECIL (
ID_DETCIL INTEGER NOT NULL,
MOVCIL INTEGER NOT NULL,
CIL INTEGER NOT NULL,
PLAZO INTEGER DEFAULT 0,
FECHADEV DATE,
OBSERVACION VARCHAR(50),
DOCDEV VARCHAR(15),
LUGAR VARCHAR(15)
);
CREATE TABLE MOVCILINDROS (
ID_MOV INTEGER NOT NULL,
NOMDESTINO INTEGER NOT NULL,
SERIE VARCHAR(3) NOT NULL,
DOCUMENTO VARCHAR(10) NOT NULL,
FECHADOC DATE NOT NULL,
VENDEDOR INTEGER NOT NULL
);
CREATE TABLE TIPOGASES (
ID INTEGER NOT NULL,
TIPOGAS VARCHAR(10) NOT NULL COLLATE ES_ES_CI_AI
);
ALTER TABLE CILINDROS ADD PRIMARY KEY (ID_CILINDRO);
ALTER TABLE CLIEPROV ADD PRIMARY KEY (ID_CLIENTE);
ALTER TABLE DETALLECIL ADD PRIMARY KEY (ID_DETCIL);
ALTER TABLE MOVCILINDROS ADD PRIMARY KEY (ID_MOV);
ALTER TABLE TIPOGASES ADD CONSTRAINT PK_TIPOGASES PRIMARY KEY (ID);
ALTER TABLE CILINDROS ADD CONSTRAINT FK_CILINDROS_1 FOREIGN KEY (TIPOGASID) REFERENCES TIPOGASES (ID) ON UPDATE CASCADE;
ALTER TABLE CILINDROS ADD FOREIGN KEY (PROPIETARIO) REFERENCES CLIEPROV (ID_CLIENTE) ON DELETE NO ACTION ON UPDATE CASCADE;
ALTER TABLE DETALLECIL ADD CONSTRAINT FKDETALLECIL_CIL FOREIGN KEY (CIL) REFERENCES CILINDROS (ID_CILINDRO) ON DELETE NO ACTION ON UPDATE CASCADE;
ALTER TABLE DETALLECIL ADD FOREIGN KEY (MOVCIL) REFERENCES MOVCILINDROS (ID_MOV) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE MOVCILINDROS ADD CONSTRAINT FK_MOVCILINDROS_DEST FOREIGN KEY (NOMDESTINO) REFERENCES CLIEPROV (ID_CLIENTE) ON DELETE NO ACTION ON UPDATE CASCADE;
ALTER TABLE MOVCILINDROS ADD FOREIGN KEY (VENDEDOR) REFERENCES PERSONAL (ID_PERSONAL) ON DELETE NO ACTION ON UPDATE CASCADE;
Si bien la consulta no es lenta (Al menos no mucho). Me preocupa que no este debidamente optimizada. Viendo las estadisticas de los indices se muestra la siguiente selectividad:
RDB$FOREIGN5 24.59
RDB$FOREIGN12 2.48
Me pregunto ¿De que manera se puede mejorar esta consulta?
Gracias por la atención prestada...