Fórum Otimizar SQL #253305
04/10/2004
0
Gente fiz uma consulta SQL, mas ela esta um pouco lenta, alguem poderia me dar um help de como posso melhora-la.
Desde já agradeço.
SELECT P.PRODUTO_ID, P.DESCRICAO,P.REF_FORNECEDOR, C.COR, T.TAMANHO, M.MODELO
FROM PRODUTOS P LEFT JOIN COR C LEFT JOIN TAMANHO T LEFT JOIN MODELO M
ON C.COR_ID = P.COR_ID
ON T.TAMANHO_ID = P.TAMANHO_ID
ON M.MODELO_ID = P.MODELO_ID
WHERE UPPER(P.DESCRICAO)LIKE UPPER (´c¬´)
ORDER BY DESCRICAO
Debug
Curtir tópico
+ 0Posts
04/10/2004
Afarias
a linha acima não permite o otimizador usar o índice de descrição.
1- vc não deve usar uma função no campo de consulta
--> UPPER(P.DESCRICAO)
2- se for usar parâmetros, troque LIKE por STARTING
T+
Gostei + 0
04/10/2004
Debug
Me corrija se estiver errado, por favor.
SELECT P.PRODUTO_ID, P.DESCRICAO,P.REF_FORNECEDOR, C.COR, T.TAMANHO, M.MODELO
FROM PRODUTOS P LEFT JOIN COR C LEFT JOIN TAMANHO T LEFT JOIN MODELO M
ON C.COR_ID = P.COR_ID
ON T.TAMANHO_ID = P.TAMANHO_ID
ON M.MODELO_ID = P.MODELO_ID
WHERE P.DESCRICAO STARTING WITH (´C´)
ORDER BY DESCRICAO
Melhorou, mas muito pouco, percebi se eu tirar o ORDER BY a consulta fica muito mais rapida. O codigo acima esta certo? Pode melhor?
Muito obrigado por sua atenção. Valeu mesmo!
Gostei + 0
04/10/2004
Vinicius2k
A não ser q eu não tenha entendido o contexto desta consulta, no meu entender os joins estão colocados de forma incorreta...
1. As tabelas tem índices pelo ´ID´, normalmente PKs ?
2. As colunas do join são FKs na tabela PRODUTOS (se a ligação estiver sendo feita pelas PKs isso não fará diferença) ?
3. Existe índice pela coluna DESCRICAO na tabela PRODUTOS ?
Resumidamente na estrutura :
create table COR( COR_ID integer not null, COR varchar(10) ); alter table COR add constraint PK_COR primary key (COR_ID); /* ------------------- */ create table TAMANHO( TAMANHO_ID integer not null, TAMANHO varchar(10) ); alter table TAMANHO add constraint PK_TAMANHO primary key (TAMANHO_ID); /* ------------------- */ create table MODELO( MODELO_ID integer not null, MODELO varchar(10) ); alter table MODELO add constraint PK_MODELO primary key (MODELO_ID); /* ------------------- */ create table PRODUTOS( PRODUTO_ID integer not null, DESCRICAO varchar(30), REF_FORNECEDOR varchar(10), COR_ID integer, TAMANHO_ID integer, MODELO_ID integer ); alter table PRODUTOS add constraint PK_PRODUTOS primary key (PRODUTO_ID); alter table PRODUTOS add constraint FK_PRODUTOS_COR foreign key (COR_ID) references COR (COR_ID); alter table PRODUTOS add constraint FK_PRODUTOS_TAMANHO foreign key (TAMANHO_ID) references TAMANHO (TAMANHO_ID); alter table PRODUTOS add constraint FK_PRODUTOS_MODELO foreign key (MODELO_ID) references MODELO (MODELO_ID); create index IX_PRODUTOS_A on PRODUTOS (DESCRICAO);
Este select, à princípio, seria o mais otimizado possível:
select P.PRODUTO_ID, P.DESCRICAO, P.REF_FORNECEDOR, C.COR, T.TAMANHO, M.MODELO from PRODUTOS P left join COR C on (P.COR_ID = C.COR_ID) left join TAMANHO T on (P.TAMANHO_ID = T.TAMANHO_ID) left join MODELO M on (P.MODELO_ID = M.MODELO_ID) where P.DESCRICAO starting with (´C´) order by P.DESCRICAO
Espero ter ajudado...
T+
Gostei + 0
05/10/2004
Debug
As Pks e os index, das tabelas estavam igual ao que vc criou, mas os joins estavam errados.
Agora entendi como fazer um join com varias tabelas.
Muito obrigado. Valeuuuuuuuuuuuuuuuuuu.
Gostei + 0
05/10/2004
Vinicius2k
Quando pensar uma query, aplique-a, primeiramente, num front-end que de suporte à analise ou pelo menos visualização do PLAN adotado pelo servidor (IBExpert, IBConsole, Etc), veja a informação do PLAN e nunca permita que a opção NATURAL apareca... seus índices (sejam índices normais, PKs ou FKs) sempre devem ser usados...
Se vc observar o resultado do meu PLAN (último quote), o servidor encontrou índices suficientes para executar a query, foi isso que a deixou rápida...
Para vc compreender melhor os Joins veja a respos do colega afarias:
http://delphiforum.icft.com.br/forum/viewtopic.php?t=49308
E se, dentro da cláusula ON, vc realizar mais de uma comparação, estas comparações devem conter as mesmas colunas do índice, e se estiver trabalhando com tipos de dados diferentes no índice, dê preferencia à esta sequência: [b:87ef0f9cbb]Smallint -> Integer -> Date -> String[/b:87ef0f9cbb].
E no Join :
1. T1.Smallint = T2.Smallint
2. T1.Integer = T2.Integer
3. T1.Date = T2.Date
4. T1.String = T2.String
T+
Gostei + 0
05/10/2004
Amjorge
poderia usar ao invés de:
WHERE P.DESCRICAO starting with (´C´)
este:
WHERE
P.DESCRICAO >= ´C´
AND P.DESCRICAO < ´D´
AND P.DESCRICAO starting with (´C´)
Se vc. puder, por favor, dê uma testada e depois nos informe. Obrigado.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)