Benutzer mit den meisten Antworten
SQL und Index...

Frage
-
Hallo,
ich muss ein Datumsformat abspeichern ohne den Typ Date zu verwenden.
Es wird abgelegt in ein Char(10) Feld...
Um folgende Abfrage zu beschleunigen habe ich einfach einen Index auf dieses Feld
gelegt...
select blabla from blabla where (day(anlageam) >= '05' and MONTH(anlageam) >= '01' and YEAR(anlageam) >= '2011' ) AND
(day(anlageam) <= '17' and MONTH(anlageam) <= '01' and YEAR(anlageam) <= '2011' )Da ich extrem mit dem Ausführungsplan auf Kriegsfuss stehe und diesen bis heute nicht wirklich verstehe,
einfach mal eine direkte Frage :Reicht dieser Index aus ?
Create index AnlangeAM on blabla ( AnlageAM )
oder geht sowas auch :
Create index AnlangeAM1 on blabla ( Day(AnlageAM) )
Create index AnlangeAM2 on blabla ( Month(AnlageAM) )
Create index AnlangeAM3 on blabla ( Year(AnlageAM) )oder muss ich neben dem Feld Anlage noch 3 weitere Felder speichenr um die 3
Informationen zusätzlich noch zu haben und dann jeweils einen Index auf das Feld ?Danke euch,
Mario
Antworten
-
hi Mario,
> ich muss ein Datumsformat abspeichern ohne den Typ Date zu verwenden.
Warum?
Deine DAY(), MONTH() und YEAR() Funktionen müssen dann dein CHAR(10) implizt convertieren.
> Create index AnlangeAM1 on blabla ( Day(AnlageAM) )
Das geht nicht. Du kannst allerdings einen Index auf berechnete Spalten - CONVERT(DATE, [AngelegtAm], 101) bzw. das entsprechende Format - legen.
http://msdn.microsoft.com/de-de/library/ms186241.aspx
http://msdn.microsoft.com/de-de/library/ms187928.aspx
http://msdn.microsoft.com/de-de/library/ms187928.aspxCREATE TABLE #test ( ID INT , cdate CHAR(10) , ddate AS CONVERT(DATE, cdate, 101) ) ; CREATE INDEX ix_test_1 ON #test (ddate) ; INSERT INTO #test ( id, cdate ) VALUES ( 1, '12/31/1900' ) ; SELECT * FROM #test ; DROP TABLE #test ;
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Bearbeitet Robert BreitenhoferModerator Montag, 7. März 2011 14:08 Hyperlink als Hyperlink
- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13
-
Warum machst Du es Dir so kompliziert? Warum verwendest Du nicht einen der für Datumswerte vorgesehenen Datentypen? Sofern es nicht einen wirklich guten Grund gibt, warum das als char(10) gespeichert werden muss, sollte Du diese Idee schnellstens verwerfen.
Stefan hat ja bereits die Idee der Indizes auf berechnete Spalte eingebracht. Wenn Du diesen Datumsstring vorher zusammensetzt und in die Abfrage einbaust so etwa wie
DECLARE @DatumVon char(10);
DECLARE @DatumBis char(10);SELECT @DatumVon = < hier die einzelnen Werte zusammensetzen ...> -- das gleiche für @DatumBis
select blabla from blabla where anlageam >= @DatumVon AND anlageam <= @DatumBis
könnte auch ein Index nur auf AnlageAM wieder Sinn machen.
-- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13
-
Hallo,
ich muss ein Datumsformat abspeichern ohne den Typ Date zu verwenden.
Es wird abgelegt in ein Char(10) Feld...
-- Hallo Mario, -- -- Nehmen wir an, -- dass der Datentype Date und Date/Convert-Funktionen nicht verwendet werden dürfen -- und das Datum als char(10) gespeichert werden muss. use tempdb go -- Testtabelle create table Blabla ( BlablaID int identity primary key not null ,AnlageAm char(10) not null ,AnlageAmIndex int not null ) go -- Index mit eingeschlossenen Spalten -- http://msdn.microsoft.com/de-de/library/ms190806.aspx create nonclustered index IX_Blabla_AnlageAmIndex_inc_AnlageAm_BlablaID on Blabla(AnlageAmIndex asc) include(AnlageAm,BlablaID) go -- liefert dd-mm-yyyy als char(10) zurück create function dbo.GetDmyAsChar10 ( @day int ,@month int ,@year int ,@delimiter char(1) ) returns char(10) begin return right(cast(100+@day as char(3)),2) + @delimiter + right(cast(100+@month as char(3)),2) + @delimiter + cast(@year as char(4)) end go -- liefert yyyymmdd als int zurück create function dbo.GetYmdAsInt ( @day int ,@month int ,@year int ) returns int begin return @year * 10000 + @month * 100 + @day end go -- die SP persistiert Daten in der Tabelle Blabla und liefer ID zurück create proc InsertIntoBlabla ( @blablaID int out ,@anlageAmJahr int ,@anlageAmMohnat int ,@anlageAmTag int ) as begin declare @delimiter char(1) declare @anlageAm char(10) declare @anlageAmIndex int
set @delimiter = '-' set @anlageAm = dbo.GetDmyAsChar10(@anlageAmTag,@anlageAmMohnat,@anlageAmJahr,@delimiter) set @anlageAmIndex = dbo.GetYmdAsInt(@anlageAmTag,@anlageAmMohnat,@anlageAmJahr) insert into Blabla (AnlageAm,AnlageAmIndex) values(@anlageAm,@anlageAmIndex) set @blablaID = scope_identity() end go -- Testaufruf der Prozedur InsertIntoBlabla declare @blablaID int exec InsertIntoBlabla @blablaID out,@anlageAmJahr=2011,@anlageAmMohnat=2,@anlageAmTag=19 -- ID select @blablaID as [Blabla.BlablaID] go -- persistierte Daten select * from Blabla -- Abfrage, die BETWEEN (Transact-SQL) verwendet -- http://msdn.microsoft.com/de-de/library/ms187922.aspx select BlablaID, AnlageAm from Blabla where AnlageAmIndex between dbo.GetYmdAsInt(1,1,2011) and dbo.GetYmdAsInt(1,1,2012) go -- drops drop proc InsertIntoBlabla go drop function GetDmyAsChar10, GetYmdAsInt go drop table Blabla go -- hth- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13
Alle Antworten
-
hi Mario,
> ich muss ein Datumsformat abspeichern ohne den Typ Date zu verwenden.
Warum?
Deine DAY(), MONTH() und YEAR() Funktionen müssen dann dein CHAR(10) implizt convertieren.
> Create index AnlangeAM1 on blabla ( Day(AnlageAM) )
Das geht nicht. Du kannst allerdings einen Index auf berechnete Spalten - CONVERT(DATE, [AngelegtAm], 101) bzw. das entsprechende Format - legen.
http://msdn.microsoft.com/de-de/library/ms186241.aspx
http://msdn.microsoft.com/de-de/library/ms187928.aspx
http://msdn.microsoft.com/de-de/library/ms187928.aspxCREATE TABLE #test ( ID INT , cdate CHAR(10) , ddate AS CONVERT(DATE, cdate, 101) ) ; CREATE INDEX ix_test_1 ON #test (ddate) ; INSERT INTO #test ( id, cdate ) VALUES ( 1, '12/31/1900' ) ; SELECT * FROM #test ; DROP TABLE #test ;
Microsoft MVP Office Access
https://mvp.support.microsoft.com/profile/Stefan.Hoffmann- Bearbeitet Robert BreitenhoferModerator Montag, 7. März 2011 14:08 Hyperlink als Hyperlink
- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13
-
Warum machst Du es Dir so kompliziert? Warum verwendest Du nicht einen der für Datumswerte vorgesehenen Datentypen? Sofern es nicht einen wirklich guten Grund gibt, warum das als char(10) gespeichert werden muss, sollte Du diese Idee schnellstens verwerfen.
Stefan hat ja bereits die Idee der Indizes auf berechnete Spalte eingebracht. Wenn Du diesen Datumsstring vorher zusammensetzt und in die Abfrage einbaust so etwa wie
DECLARE @DatumVon char(10);
DECLARE @DatumBis char(10);SELECT @DatumVon = < hier die einzelnen Werte zusammensetzen ...> -- das gleiche für @DatumBis
select blabla from blabla where anlageam >= @DatumVon AND anlageam <= @DatumBis
könnte auch ein Index nur auf AnlageAM wieder Sinn machen.
-- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13
-
Hallo,
ich muss ein Datumsformat abspeichern ohne den Typ Date zu verwenden.
Es wird abgelegt in ein Char(10) Feld...
-- Hallo Mario, -- -- Nehmen wir an, -- dass der Datentype Date und Date/Convert-Funktionen nicht verwendet werden dürfen -- und das Datum als char(10) gespeichert werden muss. use tempdb go -- Testtabelle create table Blabla ( BlablaID int identity primary key not null ,AnlageAm char(10) not null ,AnlageAmIndex int not null ) go -- Index mit eingeschlossenen Spalten -- http://msdn.microsoft.com/de-de/library/ms190806.aspx create nonclustered index IX_Blabla_AnlageAmIndex_inc_AnlageAm_BlablaID on Blabla(AnlageAmIndex asc) include(AnlageAm,BlablaID) go -- liefert dd-mm-yyyy als char(10) zurück create function dbo.GetDmyAsChar10 ( @day int ,@month int ,@year int ,@delimiter char(1) ) returns char(10) begin return right(cast(100+@day as char(3)),2) + @delimiter + right(cast(100+@month as char(3)),2) + @delimiter + cast(@year as char(4)) end go -- liefert yyyymmdd als int zurück create function dbo.GetYmdAsInt ( @day int ,@month int ,@year int ) returns int begin return @year * 10000 + @month * 100 + @day end go -- die SP persistiert Daten in der Tabelle Blabla und liefer ID zurück create proc InsertIntoBlabla ( @blablaID int out ,@anlageAmJahr int ,@anlageAmMohnat int ,@anlageAmTag int ) as begin declare @delimiter char(1) declare @anlageAm char(10) declare @anlageAmIndex int
set @delimiter = '-' set @anlageAm = dbo.GetDmyAsChar10(@anlageAmTag,@anlageAmMohnat,@anlageAmJahr,@delimiter) set @anlageAmIndex = dbo.GetYmdAsInt(@anlageAmTag,@anlageAmMohnat,@anlageAmJahr) insert into Blabla (AnlageAm,AnlageAmIndex) values(@anlageAm,@anlageAmIndex) set @blablaID = scope_identity() end go -- Testaufruf der Prozedur InsertIntoBlabla declare @blablaID int exec InsertIntoBlabla @blablaID out,@anlageAmJahr=2011,@anlageAmMohnat=2,@anlageAmTag=19 -- ID select @blablaID as [Blabla.BlablaID] go -- persistierte Daten select * from Blabla -- Abfrage, die BETWEEN (Transact-SQL) verwendet -- http://msdn.microsoft.com/de-de/library/ms187922.aspx select BlablaID, AnlageAm from Blabla where AnlageAmIndex between dbo.GetYmdAsInt(1,1,2011) and dbo.GetYmdAsInt(1,1,2012) go -- drops drop proc InsertIntoBlabla go drop function GetDmyAsChar10, GetYmdAsInt go drop table Blabla go -- hth- Als Antwort markiert Robert BreitenhoferModerator Montag, 7. März 2011 14:13