Avatar billede sblar Nybegynder
26. februar 2003 - 08:47 Der er 3 kommentarer og
2 løsninger

Index vs. table scan

Jeg har følgende batch:
DECLARE
@Latest CHAR (12),
@D CHAR(6), -- Dato
@T CHAR(6)  -- Tid
SET @Latest = '030225150237'
SET @D = substring(@Latest,1,6)
SET @T = substring(@Latest,7,6)
select * FROM dbo.Li_data WHERE (DATO >= @D) AND (Tid >= @T)

Jeg har oprettet et index (IX_Li_Data_1) i tabellen LI_data på DATO, TID.

Sp. 1:
Er der der nogen der forklare hvorfor ovenstående batch udfører en table scan og ikke bruger index?
Følgende *bruger* index og kører derfor *meget* hurtigere:
select * from dbo.Li_data WHERE
(DATO >= '030225') AND (TID >= '150237')

Jeg behøver vel ikke at sige at de 2 batches returnerer præcis det samme.

Sp. 2:
Den første gang jeg kører batchen (den langsomme) gik der ca. 1 min. (ca. 2000 poster) næste gang tog det ca. 12 sek. 3. og efterfølgende forsøg tager ca. 2 sek.
Hvordan f..... hænger det lige sammen?


Her ses execution plan for de 2 forskellige statements som viser at den første bruger table scan og den næste bruger indexet.

StmtText                                                                                               
-------------------------------------------------------------------------------------------------------
DECLARE
@Latest CHAR (12),
@D CHAR(6), -- Dato
@T CHAR(6)  -- Tid
SET @Latest = '030225150237'

SET @D = substring(@Latest,1,6)

SET @T = substring(@Latest,7,6)

select * from dbo.Li_data WHERE (DATO >= '030225') AND (TID >= '150237')

(4 row(s) affected)

StmtText                                                                                                                                                                                                       
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([lidata0].[dbo].[Li_Data]))
      |--Index Seek(OBJECT:([lidata0].[dbo].[Li_Data].[IX_Li_Data_1]), SEEK:(([Li_Data].[DATO], [Li_Data].[TID]) >= (Convert([@1]), Convert([@2]))),  WHERE:([Li_Data].[TID]>=Convert([@2])) ORDERED FORWARD)

(2 row(s) affected)

StmtText                                                         
------------------------------------------------------------------

select * FROM dbo.Li_data WHERE (DATO >= @D) AND (Tid >= @T)

(1 row(s) affected)

StmtText                                                                                                                       
--------------------------------------------------------------------------------------------------------------------------------
  |--Table Scan(OBJECT:([lidata0].[dbo].[Li_Data]), WHERE:([Li_Data].[DATO]>=Convert([@D]) AND [Li_Data].[TID]>=Convert([@T])))

(1 row(s) affected)
Avatar billede techhouse Nybegynder
26. februar 2003 - 09:01 #1
Hvorfor er din Dato og Tid ikke et felt af type datetime, så kan du benytte
select * from dbo.Li_data WHERE MyDate >='02/25/03 15:02:27'
Dette vil gøre din query mange mange gange hurtigere!

Din kørsel gemmes af serveren når du laver den første gang og genbruges herefter.
/Thomas
Avatar billede sblar Nybegynder
26. februar 2003 - 09:31 #2
Da der ikke må ændres på rådata, er det ikke muligt at gemme dato, tid som datetime.
Hvorfor er en genbrugt kørsel hurtigere? Hvad er det der bliver gemt, data eller statement?
Avatar billede techhouse Nybegynder
26. februar 2003 - 10:21 #3
Serveren gemmer det index som den har lavet
/thomas
Avatar billede hsloth Novice
27. februar 2003 - 09:49 #4
Har du prøvet med et hint på det langsomme select ?

Man skal være opmærksom på at
  1) select * from dbo.Li_data WHERE MyDate >='02/25/03 15:02:27'
    og
  2) select * from dbo.Li_data WHERE (DATO >= '030225') AND (TID >= '150237')
Er helt forskellige.

F.eks. vil en record fra d. 26/2 kl 14 blive hentet af 1), men ikke af 2)
Avatar billede sblar Nybegynder
27. februar 2003 - 10:47 #5
Tak for svarene begge to selv om jeg ikke rigtigt kunne bruge dem. Jeg har tilføjet et felt af typen datetime istedet efter jeg opdagede det samme som du gjorde hsloth.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester