Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Leonardo Campos

Performance de SELECT

Recommended Posts

Pessoal,

 

Considerando que em todos os cadastros do sistema em que trabalho tem datas de vigências, qual seria o método mais eficiente para realizar uma consulta como, por exemplo, trazer o código dos serviços e o código da tabela de preço vigente para uma determinada data?

 

Para exemplificar execute o código abaixo em uma base de teste:

 

IF(OBJECT_ID('TABPRECO') IS NOT NULL)
  DROP TABLE TABPRECO
GO
IF(OBJECT_ID('SERVICO') IS NOT NULL)
  DROP TABLE SERVICO
GO


CREATE TABLE SERVICO (
  SERV_ID INT NOT NULL PRIMARY KEY,
  SERV_NOME VARCHAR(16) NOT NULL
)
GO
INSERT INTO SERVICO VALUES (1, 'Serv 01')
INSERT INTO SERVICO VALUES (2, 'Serv 02')
GO


CREATE TABLE TABPRECO (
  TAPR_ID INT NOT NULL PRIMARY KEY,
  SERV_ID INT NOT NULL FOREIGN KEY REFERENCES SERVICO(SERV_ID),
  TAPR_DTVIG SMALLDATETIME NOT NULL,

  CONSTRAINT UNQ_SERVID_DTVIG UNIQUE (SERV_ID, TAPR_DTVIG)
)
GO
INSERT INTO TABPRECO VALUES (1, 1, '2008-08-01')
INSERT INTO TABPRECO VALUES (2, 1, '2008-09-01')
INSERT INTO TABPRECO VALUES (3, 1, '2008-10-01')
INSERT INTO TABPRECO VALUES (4, 2, '2008-08-15')
INSERT INTO TABPRECO VALUES (5, 2, '2008-09-15')
INSERT INTO TABPRECO VALUES (6, 2, '2008-10-15')


-- Consulta 01
SELECT TAPR.SERV_ID,
       TAPR.TAPR_ID
  FROM (
        SELECT SERV.SERV_ID,
               MAX(TAPR.TAPR_DTVIG) TAPR_DTVIG
          FROM SERVICO SERV
          LEFT JOIN TABPRECO TAPR
            ON TAPR.SERV_ID = SERV.SERV_ID
         WHERE TAPR.TAPR_DTVIG < GETDATE()
         GROUP BY SERV.SERV_ID
       ) TPSE
 INNER JOIN TABPRECO TAPR
    ON TAPR.SERV_ID = TPSE.SERV_ID
   AND TAPR.TAPR_DTVIG = TPSE.TAPR_DTVIG


-- Consulta 02
SELECT SERV.SERV_ID,
       (
         SELECT TOP 1 TAPR.TAPR_ID
           FROM TABPRECO TAPR
          WHERE TAPR.SERV_ID = SERV.SERV_ID
            AND TAPR.TAPR_DTVIG < GETDATE()
          ORDER BY TAPR.TAPR_DTVIG DESC
       ) TAPR_ID
  FROM SERVICO SERV

 

Ambos os SELECTs retornam os mesmos dados, mas o primeiro usa MAX e faz um novo JOIN com a mesma tabela e o segundo usa SELECT no lugar dos campos a serem selecionados.

 

Qual dessas consultas é considerada melhor em termo de desempenho?

Existe alguma outra maneira mais eficiente para retornar os mesmos dados?

 

Obs.: A tabela de serviços é pequena, mas imagine que no lugar dela fosse uma tabela com milhares de registros, onde haveria grande impacto de performance.

 

Obrigado à todos! http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ola Leandro.

 

Criei o seguinte ambiente:

 

SERVICO : 1.000.000 Registros

TABPRECO : 3.000.000 Registros (3 para cada servico)

 

1 Consulta : 25 Segundos

2 Consulta : 17 Segundos

3 Consulta : 14 Segundos

 

 

-- 3a. consulta

 

SELECT TAPR.SERV_ID

, TAPR.TAPR_ID

FROM (SELECT SERV.SERV_ID,

MAX(TAPR.TAPR_DTVIG) TAPR_DTVIG

FROM SERVICO SERV

JOIN TABPRECO TAPR ON TAPR.SERV_ID = SERV.SERV_ID

WHERE TAPR.SERV_ID = SERV.SERV_ID

AND TAPR.TAPR_DTVIG < GETDATE()

GROUP BY SERV.SERV_ID

) TPSE

JOIN TABPRECO TAPR ON TAPR.SERV_ID = TPSE.SERV_ID

AND TAPR.TAPR_DTVIG = TPSE.TAPR_DTVIG

 

 

Abraco

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pois é... Reparei que trocou o LEFT JOIN pelo JOIN. Foi um descuido ao fazer a query mesmo, considerando que pra todo serviço há um preço e, se não há preço, não há como vender! rsrs Fiquei mais na dúvida se teria problemas de performance em relacionar as tabelas utilizando um campo do tipo smalldatetime (junto com o código do serviço). Mas já que ainda foi mais rápido, bom demais!

 

Se alguém souber outra maneira de realizar esta mesma consulta, o código será bem vindo!

 

Obrigado! http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.