none
Performance von TOP 1 RRS feed

  • Frage

  • Hallo zusammen!

    Folgende Konstellation:

    3 Tabellen: Adressen, Ansprechpartner, Aktivitäten (ca. 1,2 Mio Datensätze)

    In den Aktivitäten sind alle möglichen Aktivitäten zu Adressen/Ansprechpartner abgelegt.

    In unserer Applikation kann man bei einem AP in einer Griddarstellung die Aktivitäten anzeigen. Zuvor möchten wir mit einem Select das neueste Aktivitätendatum ermitteln:

    select top 1 aktDatum as maxAktdatum from Aktivitaeten where aktANPLFDNR=' 200213315' order by aktDatum desc 

    Gibt es zu dem Ansprechpartner mind. eine Aktivität so is der obige Select sehr schnell.

    Gibt es aber bisher KEINE Aktivität, dann benötigt dieser Select 2-3 min!

    Das Verhalten ist bei SQL 2014 genau so wie bei SQL 2017.

    Einen Index über die Spalte aktanplfdnr haben wir.

    Hat jemand eine Idee woran das liegen könnte und wie ich das Lösen kann?

    Grüße

    Jörg Schneider


    Jörg Schneider

    Mittwoch, 19. September 2018 07:13

Antworten

  • Hallo Jörg,

    wenn ein Index auf [aktANPLFDNR] liegt, dann wird - zurecht - die vollständige Tabelle gescannt (leider hast Du keinen Execution Plan beigefügt!).

    Ich habe mal versucht, Dein Beispiel nachzuvollziehen (auch hier wären ein paar Beispieldaten wünschenswert gewesen :) ).

    USE tempdb;
    GO
    
    CREATE TABLE dbo.demo
    (
    	Id				INT	NOT NULL IDENTITY (1, 1),
    	AnsprechPartner	TINYINT NOT NULL,
    	aktANPLFDNR		INT NOT NULL,
    	C1				CHAR(1000),
    	aktDatum		DATETIME NOT NULL	DEFAULT (DATEADD(DAY, CAST(RAND() * 365 * -1 AS INT), GETDATE()))
    );
    GO
    
    
    SET NOCOUNT ON;
    
    DECLARE @AnsprechPartner TINYINT;
    DECLARE @aktANPLFDNR INT;
    DECLARE @C1 CHAR(1000);
    
    DECLARE c CURSOR FORWARD_ONLY FAST_FORWARD
    FOR
    	SELECT	severity, language_id, CAST(text AS CHAR(1000))
    	FROM	sys.messages;
    
    OPEN c
    
    FETCH NEXT FROM c INTO @AnsprechPartner, @aktANPLFDNR, @C1
    WHILE @@FETCH_STATUS != -1
    BEGIN
    	INSERT INTO dbo.demo (AnsprechPartner, aktANPLFDNR, C1)
    	VALUES (@AnsprechPartner, @aktANPLFDNR, @C1);
    
    	FETCH NEXT FROM c INTO @AnsprechPartner, @aktANPLFDNR, @C1
    END
    GO
    
    CLOSE c;
    DEALLOCATE c;
    GO
    

    Mit dem obigen Skript erzeuge ich eine Tabelle mit ca. 280.000 Datensätzen mit einem willkürlichen Daten für jeden Eintrag. Zusätzlich lege ich - so, wie ich Deine Anforderungen lese - mal zwei Indexe an. Zum einen C.I. und zum anderen den von Dir genannten Index auf aktANPLFDNR.

    Der Datentyp ist hier zunächst irrelevant, da ein (VAR)CHAR sich dem INT "beugen" muss - ist also für die Ausführung der Abfrage zunächst irrelevant.

    CREATE UNIQUE CLUSTERED INDEX cuix_demo_id ON dbo.demo(Id);
    CREATE NONCLUSTERED INDEX nix_demo_aktANPLFDNR ON dbo.demo (aktANPLFDNR)

    Mehr Informationen gibt Dein Sachverhalt aktuell nicht her.

    Wenn ich nun folgende Abfrage ausführe, erhalte daraus den nachfolgenden Ausführungsplan:

    SELECT	TOP (1) aktDatum
    FROM	dbo.demo
    WHERE	aktANPLFDNR = '1044'
    ORDER BY
    		aktDatum DESC
    OPTION	(QUERYTRACEON 9130);
    GO

    Die Erwartung ist, dass zunächst mit einem INDEX-SEEK das Prädikat gesucht wird und anschließend das letzte Datum mit einem Eintrag.

    Das Ergebnis ist "erschreckend" da die komplette Tabelle (CLUSTERED INDEX SCAN) zunächst durchsucht wird und in einem FILTER erst auf die Teilmenge der gesuchten aktANPLFDNR reduziert wird. Das hängt damit zusammen, dass Microsoft SQL Server - bedingt durch den TOP-Operator - den INDEX nicht effizient verwenden kann, da dann aktDATUM (relevant für den SORT-Operator) nicht kennt. Für den Filter müssen bereits aktANPLFDNR und aktDATUM bereits vorhanden sein, um später zu sortieren! Somit scheidet die Verwendung des gesetzten Operators aus.

    Nachdem - in meinem Beispiel - 280.000 Datensätze geliefert wurden, kann nach der LFDNR gesucht werden. Diese Teilmenge wird dann sortiert und der TOP-Operator bricht automatisch nach dem erhalt des ersten Datensatzes die Operation ab und die Abfrage wird beendet.

    Dieses Problem kannst Du am einfachsten umgehen, wenn aktDATUM Bestandteil Deines Index ist.

    CREATE NONCLUSTERED INDEX nix_demo_aktANPLFDNR ON dbo.demo ( aktANPLFDNR, aktDatum ) WITH DROP_EXISTING;

    Die gleiche Abfrage mit dem oben implementierten Index ist deutlich performanter. Die Sortierung von aktDATUM ist vollkommen irrelevant für Microsoft SQL Server. ist das Attribut DESC sortiert, kann SQL Server gleich den ersten Datensatz verwenden; ist das Attribut ASC sortiert, nimmt man halt den letzten Datensatz.

    Bezüglich der Variationen in der Laufzeit können noch zwei weitere Punkte relevant sein.

    • Der neue Query Estimator in Verbindung mit dem ASCENDING KEY Problem
    • READ COMMITTED SNAPSHOT ISOLATION und offene Transaktionen

    Eine vollständige Beschreibung dieser Problematik wäre ein Blog-Eintrag wert und würde den Sinn und Zweck dieses Forums sprengen. Eine gute Anlaufquelle wäre aber z. B. hier:

    https://www.sqlshack.com/ascending-key-and-ce-model-variation/

    Über den Zusammenhang mit lang laufenden Abfragen in Zusammenhang mit RCSI habe ich selbst geblogged, da ich bei einem Kunden ein solches Problem vorgefunden habe:

    https://www.db-berater.de/2017/04/read-committed-snapshot-isolation-und-hohe-anzahl-von-version_ghost_record_count/

    Gerne würde ich hier weiterhelfen - ohne Metadaten und genauer Datenmenge / -struktur ist das aber nur bedingt möglich. Vielleicht helfen die Anregungen aber ein wenig weiter.


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiied Master - SQL Server 2008
    Microsoft Certified Solution Master - CHARTER Data Platform
    Microsoft Certified Solution Expert - Data Platform
    db Berater GmbH
    Microsoft SQL Server Blog (german only)

    • Als Antwort markiert SchneiderJoerg Mittwoch, 19. September 2018 15:23
    Mittwoch, 19. September 2018 15:09
  • Hallo Jörg,

    Wenn ich es richtig verstanden habe, dann liegt die lange Laufzeit daran, dass der SQL Server die ganze Tabelle absuchen muss um festzustellen, dass kein Datensatz vorhanden ist. Wenn es einen Treffer gibt wird ja wegen Top 1 nicht weiter gesucht. 

    du kannst versuchen ob der Index über  aktANPLFDNR und aktDatum dir hier Vorteile verschafft.


    Benjamin Hoch
    MCSE: Data Platform & Data Management and Analytics
    MCSA: SQL Server 2012/2014 & 2016 DB Administration
    MCSA: Windows Server 2012

    • Als Antwort markiert SchneiderJoerg Donnerstag, 20. September 2018 06:53
    Mittwoch, 19. September 2018 07:40
  • Die Indexwahl wird auch durch Order By beeinflusst.
    Hier hilft ggf. ein Index

    create index myindex on mytable (aktanplfdnr, aktDatum desc)

    Zusätzlich, auch wenn es sinnfrei erscheint da die Auswahl ja bereits getroffen ist:

    select top 1 aktANPLFDNR, aktDatum as maxAktdatum from Aktivitaeten where aktANPLFDNR=' 200213315' order by aktANPLFDNR, aktDatum desc

    Dies hilft dem Optimizer bzgl. seiner Entscheidungen.
    Es wäre ja schließlich unsinnig, wenn grundsätzlich eine Suche von nicht vorhandenen Daten einen Tablescan erzwingen würde.

    • Als Antwort markiert SchneiderJoerg Donnerstag, 20. September 2018 06:52
    Mittwoch, 19. September 2018 08:50

Alle Antworten

  • Hallo Jörg,

    Wenn ich es richtig verstanden habe, dann liegt die lange Laufzeit daran, dass der SQL Server die ganze Tabelle absuchen muss um festzustellen, dass kein Datensatz vorhanden ist. Wenn es einen Treffer gibt wird ja wegen Top 1 nicht weiter gesucht. 

    du kannst versuchen ob der Index über  aktANPLFDNR und aktDatum dir hier Vorteile verschafft.


    Benjamin Hoch
    MCSE: Data Platform & Data Management and Analytics
    MCSA: SQL Server 2012/2014 & 2016 DB Administration
    MCSA: Windows Server 2012

    • Als Antwort markiert SchneiderJoerg Donnerstag, 20. September 2018 06:53
    Mittwoch, 19. September 2018 07:40
  • Die Indexwahl wird auch durch Order By beeinflusst.
    Hier hilft ggf. ein Index

    create index myindex on mytable (aktanplfdnr, aktDatum desc)

    Zusätzlich, auch wenn es sinnfrei erscheint da die Auswahl ja bereits getroffen ist:

    select top 1 aktANPLFDNR, aktDatum as maxAktdatum from Aktivitaeten where aktANPLFDNR=' 200213315' order by aktANPLFDNR, aktDatum desc

    Dies hilft dem Optimizer bzgl. seiner Entscheidungen.
    Es wäre ja schließlich unsinnig, wenn grundsätzlich eine Suche von nicht vorhandenen Daten einen Tablescan erzwingen würde.

    • Als Antwort markiert SchneiderJoerg Donnerstag, 20. September 2018 06:52
    Mittwoch, 19. September 2018 08:50
  • Sind eigentlich die Datentypen korrekt?

    aktANPLFDNR=' 200213315' sieht so aus, als ob es ein char/varchar wäre, LFDNR legt eher ein Zahlenformat nahe.

    Sollte es ein Zahlenformat sein, dann würde der Optimizer diese Zahlen auch noch in einen String umwandeln um abzugleichen, denn die umgekehrte Konvertierung des Strings in eine Zahl muss ja nicht funktionieren.


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Mittwoch, 19. September 2018 11:37
  • Diesbezüglich habe ich aus einer anderen Geschichte heraus nur mitbekommen, dass der SQL-Server die Konstante in den Feldtyp konvertiert und nicht das Feld in den Typ der Konstante, was einen Tablescan nach sich ziehe würde.

    where numericfiled = 'XX'

    führte zur Fehlermeldung dass 'XX' nicht in Integer konvertierbar sei, womit er ja recht hat.

    Mittwoch, 19. September 2018 11:53
  • SQL-Server die Konstante in den Feldtyp konvertiert und nicht das Feld in den Typ der Konstante

    Das ist nicht korrekt, was konvertiert wird, wird nach den Data type precedence (Transact-SQL) geregelt.

    Beispiel:

    select *
    from sys.objects
    where Name = {d N'2018-09-19'};

    Ergebnis:

    Das varchar Feld wird nach Datetime konvertiert, weil dieses eine höhere Rangfolge hat.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Mittwoch, 19. September 2018 12:49
  • Deswegen sage ich ja (meinen Pappenheimern) immer, sich nicht auf die automatischen Konvertierungen zu verlassen da diese im Ergebnis Indexverwendungen verhindern können und zu Teilergebnissen führen wenn unterwegs die Konvertierung fehlschlägt und der SQL abbricht.

    Je nach Situation kam es schon des öfteren vor, dass ein Select ohne Fehlermeldung vorzeitig beendet wurde und eben nur ein Teilergebnis der Daten vorlag (BI-Importe).

    Erst nach längerem Forschen und Eingrenzen konnte dann das Konvertierungsproblem erkannt und durch Korrektur des SQL's beseitigt werden.

    Und die obige Precedence zeigt ja, dass wohl eher char in int gecastet wird als umgekehrt.

    Mittwoch, 19. September 2018 13:00
  • Sollte es ein Zahlenformat sein, dann würde der Optimizer diese Zahlen auch noch in einen String umwandeln um abzugleichen, denn die umgekehrte Konvertierung des Strings in eine Zahl muss ja nicht funktionieren.


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Hallo Christoph,

    das ist nicht richtig. Dazu gibt es die Präferenzen der Datentypen in Microsoft SQL Server. Ist das Attribut numerisch, muss sich IMMER der String "beugen"

    https://docs.microsoft.com/de-de/sql/t-sql/data-types/data-type-precedence-transact-sql?view=sql-server-2017

    Der CONVERT_IMPLICIT wird dann auf das Prädikat ausgeführt.


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiied Master - SQL Server 2008
    Microsoft Certified Solution Master - CHARTER Data Platform
    Microsoft Certified Solution Expert - Data Platform
    db Berater GmbH
    Microsoft SQL Server Blog (german only)

    Mittwoch, 19. September 2018 14:33
  • Hallo Jörg,

    wenn ein Index auf [aktANPLFDNR] liegt, dann wird - zurecht - die vollständige Tabelle gescannt (leider hast Du keinen Execution Plan beigefügt!).

    Ich habe mal versucht, Dein Beispiel nachzuvollziehen (auch hier wären ein paar Beispieldaten wünschenswert gewesen :) ).

    USE tempdb;
    GO
    
    CREATE TABLE dbo.demo
    (
    	Id				INT	NOT NULL IDENTITY (1, 1),
    	AnsprechPartner	TINYINT NOT NULL,
    	aktANPLFDNR		INT NOT NULL,
    	C1				CHAR(1000),
    	aktDatum		DATETIME NOT NULL	DEFAULT (DATEADD(DAY, CAST(RAND() * 365 * -1 AS INT), GETDATE()))
    );
    GO
    
    
    SET NOCOUNT ON;
    
    DECLARE @AnsprechPartner TINYINT;
    DECLARE @aktANPLFDNR INT;
    DECLARE @C1 CHAR(1000);
    
    DECLARE c CURSOR FORWARD_ONLY FAST_FORWARD
    FOR
    	SELECT	severity, language_id, CAST(text AS CHAR(1000))
    	FROM	sys.messages;
    
    OPEN c
    
    FETCH NEXT FROM c INTO @AnsprechPartner, @aktANPLFDNR, @C1
    WHILE @@FETCH_STATUS != -1
    BEGIN
    	INSERT INTO dbo.demo (AnsprechPartner, aktANPLFDNR, C1)
    	VALUES (@AnsprechPartner, @aktANPLFDNR, @C1);
    
    	FETCH NEXT FROM c INTO @AnsprechPartner, @aktANPLFDNR, @C1
    END
    GO
    
    CLOSE c;
    DEALLOCATE c;
    GO
    

    Mit dem obigen Skript erzeuge ich eine Tabelle mit ca. 280.000 Datensätzen mit einem willkürlichen Daten für jeden Eintrag. Zusätzlich lege ich - so, wie ich Deine Anforderungen lese - mal zwei Indexe an. Zum einen C.I. und zum anderen den von Dir genannten Index auf aktANPLFDNR.

    Der Datentyp ist hier zunächst irrelevant, da ein (VAR)CHAR sich dem INT "beugen" muss - ist also für die Ausführung der Abfrage zunächst irrelevant.

    CREATE UNIQUE CLUSTERED INDEX cuix_demo_id ON dbo.demo(Id);
    CREATE NONCLUSTERED INDEX nix_demo_aktANPLFDNR ON dbo.demo (aktANPLFDNR)

    Mehr Informationen gibt Dein Sachverhalt aktuell nicht her.

    Wenn ich nun folgende Abfrage ausführe, erhalte daraus den nachfolgenden Ausführungsplan:

    SELECT	TOP (1) aktDatum
    FROM	dbo.demo
    WHERE	aktANPLFDNR = '1044'
    ORDER BY
    		aktDatum DESC
    OPTION	(QUERYTRACEON 9130);
    GO

    Die Erwartung ist, dass zunächst mit einem INDEX-SEEK das Prädikat gesucht wird und anschließend das letzte Datum mit einem Eintrag.

    Das Ergebnis ist "erschreckend" da die komplette Tabelle (CLUSTERED INDEX SCAN) zunächst durchsucht wird und in einem FILTER erst auf die Teilmenge der gesuchten aktANPLFDNR reduziert wird. Das hängt damit zusammen, dass Microsoft SQL Server - bedingt durch den TOP-Operator - den INDEX nicht effizient verwenden kann, da dann aktDATUM (relevant für den SORT-Operator) nicht kennt. Für den Filter müssen bereits aktANPLFDNR und aktDATUM bereits vorhanden sein, um später zu sortieren! Somit scheidet die Verwendung des gesetzten Operators aus.

    Nachdem - in meinem Beispiel - 280.000 Datensätze geliefert wurden, kann nach der LFDNR gesucht werden. Diese Teilmenge wird dann sortiert und der TOP-Operator bricht automatisch nach dem erhalt des ersten Datensatzes die Operation ab und die Abfrage wird beendet.

    Dieses Problem kannst Du am einfachsten umgehen, wenn aktDATUM Bestandteil Deines Index ist.

    CREATE NONCLUSTERED INDEX nix_demo_aktANPLFDNR ON dbo.demo ( aktANPLFDNR, aktDatum ) WITH DROP_EXISTING;

    Die gleiche Abfrage mit dem oben implementierten Index ist deutlich performanter. Die Sortierung von aktDATUM ist vollkommen irrelevant für Microsoft SQL Server. ist das Attribut DESC sortiert, kann SQL Server gleich den ersten Datensatz verwenden; ist das Attribut ASC sortiert, nimmt man halt den letzten Datensatz.

    Bezüglich der Variationen in der Laufzeit können noch zwei weitere Punkte relevant sein.

    • Der neue Query Estimator in Verbindung mit dem ASCENDING KEY Problem
    • READ COMMITTED SNAPSHOT ISOLATION und offene Transaktionen

    Eine vollständige Beschreibung dieser Problematik wäre ein Blog-Eintrag wert und würde den Sinn und Zweck dieses Forums sprengen. Eine gute Anlaufquelle wäre aber z. B. hier:

    https://www.sqlshack.com/ascending-key-and-ce-model-variation/

    Über den Zusammenhang mit lang laufenden Abfragen in Zusammenhang mit RCSI habe ich selbst geblogged, da ich bei einem Kunden ein solches Problem vorgefunden habe:

    https://www.db-berater.de/2017/04/read-committed-snapshot-isolation-und-hohe-anzahl-von-version_ghost_record_count/

    Gerne würde ich hier weiterhelfen - ohne Metadaten und genauer Datenmenge / -struktur ist das aber nur bedingt möglich. Vielleicht helfen die Anregungen aber ein wenig weiter.


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiied Master - SQL Server 2008
    Microsoft Certified Solution Master - CHARTER Data Platform
    Microsoft Certified Solution Expert - Data Platform
    db Berater GmbH
    Microsoft SQL Server Blog (german only)

    • Als Antwort markiert SchneiderJoerg Mittwoch, 19. September 2018 15:23
    Mittwoch, 19. September 2018 15:09
  • Ja, die Datentypen sind korrekt.

    In unserer "Sprache" sagen wir lfdnr, es sind aber charFelder


    Jörg Schneider

    Mittwoch, 19. September 2018 15:10
  • Diesbezüglich habe ich aus einer anderen Geschichte heraus nur mitbekommen, dass der SQL-Server die Konstante in den Feldtyp konvertiert und nicht das Feld in den Typ der Konstante, was einen Tablescan nach sich ziehe würde.

    where numericfiled = 'XX'

    führte zur Fehlermeldung dass 'XX' nicht in Integer konvertierbar sei, womit er ja recht hat.

    Hallo Baldur,

    obwohl hier Olaf bereits den entscheidenden Hinweis gegeben hat, muss ich da auch widersprechen. Es versteht sich natürlich von selbst, dass 'XX' nicht numerisch ist - aber was ist mit '11', '99', ...

    DROP TABLE dbo.demo;
    GO
    
    SELECT	language_id, message_id, CAST(severity AS CHAR(2)) AS severity, CAST(text AS CHAR(1000)) AS text
    INTO dbo.demo
    FROM sys.messages;
    GO
    
    CREATE NONCLUSTERED INDEX nix_demo_severity ON dbo.demo(severity);
    GO

    Das obige Skript erzeugt eine Testtabelle mit einem NCI auf dem Attribut [severity], das ein String ist.

    SELECT * FROM dbo.demo
    WHERE	severity = 12;
    
    SELECT * FROM dbo.demo
    WHERE	severity = '12';

    Die beiden obigen Abfragen erzeugen vollkommen unterschiedliche Ausführungspläne. Während Abfrage 1 einen TABLE-SCAN verwendet, kann Abfrage 2 einen performanten INDEX-SEEK anwenden.

    Der Grund für dieses Verhalten ist von Olaf bereits weiter oben erläutert worden. ANDERS jedoch sieht es aus, wenn der Datentyp des Attributs "höherrangig" ist. Gleiches Beispiel - nur diesmal ist [severity] vom Datentypen TINYINT!

    DROP TABLE dbo.demo;
    GO
    
    SELECT	language_id, message_id, severity, CAST(text AS CHAR(1000)) AS text
    INTO dbo.demo
    FROM sys.messages;
    GO
    
    CREATE NONCLUSTERED INDEX nix_demo_severity ON dbo.demo(severity);
    GO

    Wie man sehr schön erkennen kann, verwenden beide Abfragen den gleichen Plan. Während Abfrage 1 den korrekten Datentypen verwendet (TINYINT), muss Microsoft SQL Server im zweiten Beispiel das Prädikat zu einem TINYINT konvertieren. Das geht natürlich deutlich performanter als - wie im ersten Beispiel gezeigt - alle Daten der Spalte [severity] zu konvertieren.


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiied Master - SQL Server 2008
    Microsoft Certified Solution Master - CHARTER Data Platform
    Microsoft Certified Solution Expert - Data Platform
    db Berater GmbH
    Microsoft SQL Server Blog (german only)

    Mittwoch, 19. September 2018 15:19
  • Und die obige Precedence zeigt ja, dass wohl eher char in int gecastet wird als umgekehrt.

    So sieht es aus :)

    SQL Server verwendet die folgende Rangfolge für Datentypen:

    1. benutzerdefinierte Datentypen (höchster)
    2. sql_variant
    3. xml
    4. datetimeoffset
    5. datetime2
    6. datetime
    7. smalldatetime
    8. Datum
    9. Uhrzeit
    10. float
    11. real
    12. decimal
    13. money
    14. smallmoney
    15. bigint
    16. int
    17. smallint
    18. tinyint
    19. bit
    20. ntext
    21. text
    22. image
    23. timestamp
    24. uniqueidentifier
    25. nvarchar (einschließlich nvarchar(max))
    26. nchar
    27. varchar (einschließlich varchar(max))
    28. char
    29. varbinary (einschließlich varbinary(max))
    30. binary (niedrigster)


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiied Master - SQL Server 2008
    Microsoft Certified Solution Master - CHARTER Data Platform
    Microsoft Certified Solution Expert - Data Platform
    db Berater GmbH
    Microsoft SQL Server Blog (german only)

    Mittwoch, 19. September 2018 15:20
  • Hallo Uwe!

    Danke! Mit Hilfe des Index war die Abfrage jetzt absolut schnell.

    Vielen Dank auch für Deine Ausführlichen Erklärungen und Tests!



    Jörg Schneider

    Mittwoch, 19. September 2018 15:25
  • Wie ich ja oben bereits geschrieben habe, macht eben der 2-Feld-Index Sinn;-).
    Die DESC-Variante ist halt je nach Datenvolumen etwas schneller da im Index nicht erst das Ende gesucht werden muss.
    Dies ist eben meine Erfahrung im BI-Umfeld, auch wenn es (leider) nicht immer geglaubt wird.

    Es ist halt nur unschön, dass sich Antworten dazwischen schieben obwohl sie zeitlich später kommen:-(.

    • Bearbeitet Der Suchende Mittwoch, 19. September 2018 15:51
    Mittwoch, 19. September 2018 15:47
  • Diesen Index hatte ich schon im ersten Beitrag vorgeschlagen.

    Benjamin Hoch
    MCSE: Data Platform & Data Management and Analytics
    MCSA: SQL Server 2012/2014 & 2016 DB Administration
    MCSA: Windows Server 2012

    Mittwoch, 19. September 2018 15:52
  • Das sich das von selbst versteht iist für den technisch Versierten ja klar.
    Aber in diesem Beispiel hat ein User halt einen SQL gezaubert und sich nicht um den Typ des Feldes bei der Abfrage gekümmert.

    Kurzgesagt ging es nur um den Autocast.

    Mittwoch, 19. September 2018 15:54
  • create index myindex on mytable (aktanplfdnr, aktDatum desc)

    Sinnfrei finde ich das durchaus nicht. Wir werden den Index desc erzeugen!

    Danke auch für Deinen Beitrag!


    Jörg Schneider

    Donnerstag, 20. September 2018 06:52
  • Wie ich ja oben bereits geschrieben habe, macht eben der 2-Feld-Index Sinn;-).
    Die DESC-Variante ist halt je nach Datenvolumen etwas schneller da im Index nicht erst das Ende gesucht werden muss.
    Dies ist eben meine Erfahrung im BI-Umfeld, auch wenn es (leider) nicht immer geglaubt wird.

    Es ist halt nur unschön, dass sich Antworten dazwischen schieben obwohl sie zeitlich später kommen:-(.

    Ja, das Forum sortiert das ganze etwas krum ein ;)

    Jörg Schneider

    Donnerstag, 20. September 2018 06:53