Como buscar a última linha inserida numa tabela, no SQL Server

Um MCT (Microsoft Certified Trainer) de um grupo que participo fez a seguinte pergunta:

Tenho uma tabela com dois campos: data e dados. Preciso buscar a última linha inserida na tabela, ou seja, a maior data.

Como informação adicional, temos que as datas são inseridas em ordem crescente, isto é, já estão ordenadas. A solução adotada por ele foi fazer um select top 1 ordenando pela data, descendente.

Claro que o volume de dados na tabela afeta de forma negativa o resultado. Quanto mais registros, pior o desempenho.

Pensei nas seguintes situações:

  • Criar um índice nonclustered;
  • criar um índice nonclustered, incluindo o campo data;
  • criar um índice clustered no campo data;
  • criar uma chave primária int com autonumeração e buscar o valor da última chave inserida, usando funções do SQL. <<< a melhor opção, na minha opinião

Segue o código com os testes:

USE MASTER

IF EXISTS (SELECT FROM sys.databases WHERE name = 'EX')
      
DROP DATABASE EX

CREATE DATABASE EX
GO

USE 
EX

CREATE TABLE TABELA
(
      DATA 
DATETIME
      DADO 
VARCHAR(50)
)

DECLARE @X INT = 10

WHILE @X >1
BEGIN
      INSERT INTO 
TABELA VALUES (DATEADD(D, -@X, GETDATE()) , NEWID())
      
SET @X -1
END

SET 
SHOWPLAN_TEXT ON

SELECT 
FROM TABELA
/*
  |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SELECT MAX(DATA) FROM TABELA
/*
  |--Stream Aggregate(DEFINE:([Expr1004]=MAX([EX].[dbo].[TABELA].[DATA])))
       |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SELECT FROM TABELA WHERE DATA IN (SELECT MAX(DATA) FROM TABELA)
/*
  |--Nested Loops(Inner Join, WHERE:([Expr1008]=[EX].[dbo].[TABELA].[DATA]))
       |--Stream Aggregate(DEFINE:([Expr1008]=MAX([EX].[dbo].[TABELA].[DATA])))
       |    |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
       |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SELECT TOP FROM TABELA ORDER BY DATA
/*
  |--Sort(TOP 1, ORDER BY:([EX].[dbo].[TABELA].[DATA] ASC))
       |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SELECT TOP FROM TABELA ORDER BY DATA DESC
/*
  |--Sort(TOP 1, ORDER BY:([EX].[dbo].[TABELA].[DATA] DESC))
       |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SET SHOWPLAN_TEXT OFF

CREATE CLUSTERED INDEX 
IDX1 ON TABELA(DATA)

EXEC sp_helpindex TABELA
/*
index_name    index_description                 index_keys
------------- --------------------------------- ------------
IDX1          clustered located on PRIMARY      DATA
*/

SET SHOWPLAN_TEXT ON

SELECT 
FROM TABELA
/*
  |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]))
*/
SELECT MAX(DATA) FROM TABELA
/*
  |--Stream Aggregate(DEFINE:([Expr1004]=MAX([EX].[dbo].[TABELA].[DATA])))
       |--Top(TOP EXPRESSION:((1)))
            |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]),
               WHERE:([EX].[dbo].[TABELA].[DATA] IS NOT NULL) ORDERED BACKWARD)
*/

SELECT FROM TABELA WHERE DATA IN (SELECT MAX(DATA) FROM TABELA)
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Clustered Index Seek(OBJECT:([EX].[dbo].[TABELA].[IDX1]),
          SEEK:([EX].[dbo].[TABELA].[DATA] IsNotNull) ORDERED BACKWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED FORWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA DESC
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED BACKWARD)
*/

SET SHOWPLAN_TEXT OFF

DROP INDEX 
TABELA.IDX1

CREATE NONCLUSTERED INDEX IDX1 ON TABELA(DATA)

EXEC sp_helpindex TABELA
/*
index_name    index_description                 index_keys
------------- --------------------------------- ------------
IDX1          nonclustered located on PRIMARY   DATA
*/

SET SHOWPLAN_TEXT ON

SELECT 
FROM TABELA
/*
  |--Table Scan(OBJECT:([EX].[dbo].[TABELA]))
*/

SELECT MAX(DATA) FROM TABELA
/*
  |--Stream Aggregate(DEFINE:([Expr1004]=MAX([EX].[dbo].[TABELA].[DATA])))
       |--Top(TOP EXPRESSION:((1)))
            |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]),
               WHERE:([EX].[dbo].[TABELA].[DATA] IS NOT NULL) ORDERED BACKWARD)
*/

SELECT FROM TABELA WHERE DATA IN (SELECT MAX(DATA) FROM TABELA)
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
            |--Index Seek(OBJECT:([EX].[dbo].[TABELA].[IDX1]),
               SEEK:([EX].[dbo].[TABELA].[DATA] IsNotNull) ORDERED BACKWARD)
            |--RID Lookup(OBJECT:([EX].[dbo].[TABELA]), 
               SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
*/
SELECT TOP FROM TABELA ORDER BY DATA
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
            |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED FORWARD)
            |--RID Lookup(OBJECT:([EX].[dbo].[TABELA]), 
               SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA DESC
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
            |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED BACKWARD)
            |--RID Lookup(OBJECT:([EX].[dbo].[TABELA]), 
               SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
*/

SET SHOWPLAN_TEXT OFF

DROP INDEX 
TABELA.IDX1

CREATE NONCLUSTERED INDEX IDX1 ON TABELA(DATA) INCLUDE (DADO)

EXEC sp_helpindex TABELA
/*
index_name    index_description                 index_keys
------------- --------------------------------- ------------
IDX1          nonclustered located on PRIMARY   DATA
*/

SET SHOWPLAN_TEXT ON

SELECT 
FROM TABELA
/*
  |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]))
*/

SELECT MAX(DATA) FROM TABELA
/*
  |--Stream Aggregate(DEFINE:([Expr1004]=MAX([EX].[dbo].[TABELA].[DATA])))
       |--Top(TOP EXPRESSION:((1)))
            |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]),  
               WHERE:([EX].[dbo].[TABELA].[DATA] IS NOT NULL) ORDERED BACKWARD)
*/

SELECT FROM TABELA WHERE DATA IN (SELECT MAX(DATA) FROM TABELA)
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Index Seek(OBJECT:([EX].[dbo].[TABELA].[IDX1]), 
          SEEK:([EX].[dbo].[TABELA].[DATA] IsNotNull) ORDERED BACKWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED FORWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA DESC
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Index Scan(OBJECT:([EX].[dbo].[TABELA].[IDX1]), ORDERED BACKWARD)
*/

SET SHOWPLAN_TEXT OFF

DROP TABLE 
TABELA

GO

CREATE TABLE 
TABELA
(
      COD 
INT IDENTITY CONSTRAINT PK PRIMARY KEY
      DATA 
DATETIME
      DADO 
VARCHAR(50)
)

DECLARE @X INT = 10

WHILE @X >1
BEGIN
      INSERT INTO 
TABELA VALUES (DATEADD(D, -@X, GETDATE()) , NEWID())
      
SET @X -1
END

EXEC 
sp_helpindex TABELA
/*
index_name    index_description                                    index_keys
------------- ---------------------------------------------------- ------------
PK            clustered, unique, primary key located on PRIMARY    COD
*/

SET SHOWPLAN_TEXT ON

SELECT 
FROM TABELA
/*
  |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[PK]))
*/

SELECT MAX(COD) FROM TABELA
/*
  |--Stream Aggregate(DEFINE:([Expr1003]=MAX([EX].[dbo].[TABELA].[COD])))
       |--Top(TOP EXPRESSION:((1)))
            |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[PK]), ORDERED BACKWARD)
*/

SELECT FROM TABELA WHERE COD IN (SELECT MAX(COD) FROM TABELA)
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[PK]), ORDERED BACKWARD)
*/

SELECT TOP FROM TABELA ORDER BY COD
/*
  |--Top(TOP EXPRESSION:((1)))
       |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[PK]), ORDERED FORWARD)
*/

SELECT TOP FROM TABELA ORDER BY DATA DESC
/*
  |--Sort(TOP 1, ORDER BY:([EX].[dbo].[TABELA].[DATA] DESC))
       |--Clustered Index Scan(OBJECT:([EX].[dbo].[TABELA].[PK]))
*/

SET SHOWPLAN_TEXT OFF

SELECT 
@@IDENTITY 
--NULL

SELECT SCOPE_IDENTITY()
--10

SELECT IDENT_CURRENT('TABELA')
--10

INSERT INTO TABELA VALUES (GETDATE() , NEWID())

SELECT @@IDENTITY 
--11

SELECT SCOPE_IDENTITY()
--11

SELECT IDENT_CURRENT('TABELA')
--11

SET SHOWPLAN_TEXT ON

SELECT 
FROM TABELA WHERE COD IN (SELECT IDENT_CURRENT('TABELA'))
/*
  |--Clustered Index Seek(OBJECT:([EX].[dbo].[TABELA].[PK]), 
     SEEK:([EX].[dbo].[TABELA].[COD]=ident_current(N'TABELA')) ORDERED FORWARD)
*/

SELECT FROM TABELA WHERE COD IDENT_CURRENT('TABELA')
/*
  |--Clustered Index Seek(OBJECT:([EX].[dbo].[TABELA].[PK]), 
     SEEK:([EX].[dbo].[TABELA].[COD]=ident_current(N'TABELA')) ORDERED FORWARD)
*/
SET SHOWPLAN_TEXT OFF

 

Comentários (1) -

supperdownloads
supperdownloads
23/08/2010 15:36:47 #

ainda é demais pra mim..mas em breve estarei entendo isso tudo...acredito que seriua muito interessante o uso de datas e todos os banco....

Comentar

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading