none
MSSQL-Server 2017 - SQL Abfragen sehr langsam RRS feed

  • Frage

  • Hallo zusammen,

    wir haben das Problem, dass unsere Abfragen auf eine Tabelle in einer MS-SQL-DB mit ca. 15 Mio Datensätzen (170 Spalten) zunehmend mit zunehmender Datensatzanzahl langsamer werden. Die Tabelle hat eine Spalte Id (int).

    Allein in der Management-Konsole dauert ein SELECT COUNT(*) auf diese Tabelle fast 2 Minuten. Das sollte doch eigentlich im Millisekundenbereich liegen, oder???

    Was haben wir u.U. vergessen, oder was sollten wir serverseitig einstellen, damit es performanter geht?

    Für Hinweise wäre ich sehr dankbar, da in der jetzigen Konstellation die Abfragen, die über einen App-Server an die DB gesendet werden oft in einen TimeOut enden.

    Gruß Jürgen

    Dienstag, 1. Oktober 2019 11:02

Alle Antworten

  • Hallo Jürgen,

    das lässt sich mit den Angaben eigentlich gar nicht beantworten.

    Welche Version/Edition setzt ihr ein? Select @@VERSION;

    Hat die Tabelle Indizes? Welche? Passen diese zu den Statements? Gibt es einen Clustered Index? Wie ist die Fragmentierung der Indizes?

    Wie viele Zeilen sollte das Select liefern, was immer langsamer wird?

    Bei 300 Mio. Zeilen bekomme ich ein Count(*) in 5 Sekunden hin. Aber das hat keine Relevanz, da Du nicht weißt, welche Hardware ich dafür verwende. Du siehst also, so ganz pauschal geht es leider nicht.


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

    Dienstag, 1. Oktober 2019 13:57
    Beantworter
  • Hallo Jürgen,

    es gibt nicht wirklich Server-seitige Einstellung, die Abfragen langsam oder schneller werden lässt. Die Ursachen muss man selbst untersuchen. Das können veraltete Statistiken sein, defragmentierte Indizes (wobei das nicht wirklich sehr große Auswirkungen hat), schlechtes Datenbank-Design, suboptimale Abfragen, langsames I/O System, etc.

    Ein reines SELECT COUNT(*) ist in der Regel schnell durch, es sei den es gibt Sperren auf der Tabelle, dann muss die Abfrage warten; ich gehe mal davon aus, das aus der Tabelle nicht nur gelesen, sondern auch geschrieben wird.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Mittwoch, 2. Oktober 2019 05:13
  • Prüfe mal hier:
    https://docs.microsoft.com/de-de/sql/database-engine/configure-windows/server-memory-server-configuration-options?view=sql-server-2017
    Donnerstag, 3. Oktober 2019 12:26
  • Hi Jürgen,

    ich denke, dass hier noch ein paar Rahmenbedingungen fehlen, um hier weiterhelfen zu können. Wie Christoph schon geschrieben hat: welche Edition ist im Einsatz?  Dann mal die Frage: wie groß ist denn die Tabelle ? Wie viel CPUs hat der Server, wie viel Arbeitsspeicher? 

    Dann, wie Olaf schon beschrieben hat, kann es natürlich sein, dass ein anderer Prozess gerade die Abfrage blockiert.

    Wir wissen ja noch zu wenig darüber, was in der sehr breiten Tabelle alles passiert.

    Was das TimeOut angeht:  der SQL Server kennt idR kein TimeOut. Der kommt von der ClientSeite, da sich hier und da in der Programmierwelt immer irgendwelche default Timeouts verstecken.

    Schon mal den Vergleich gemacht, wie lang die Abfrage braucht, wenn man die direkt am SQL Server absetzt und meinetwegen in eine Datei lokal umlenkt vs das Result muss über das Netz an den anfragenden Rechner?

    Oder die Abfrage des App-Servers wirklich mal schnappen, von einem Management Studio ausführen und dabei die Client Statistics aktivieren. Dann sieht man mal, wie viel MD über die Leitung gehen.

    Was das Select count (*) angeht, so haben wir hier auch wieder mehrere Faktoren.

    Ich hab bei einer Tabelle das mal zum Spaß gemacht.

    Knapp 20 Millionen Zeilen bei 399 Spalten (ich muss mal den Kollegen fragen, was der da treibt....). 

    Das Ergebnis ist aber in 1 Sekunde da, weil zum Ermitteln der SQL Server nicht nativ auf die Tabelle gegangen ist, sondern einen Index genutzt hat. Daher muss der SQL Server auch weitaus weniger Datenseiten lesen, um an das Ergebnis zu kommen.  Bei Deinem count (*)  hab ich die Vermutung, dass der SQL Server sich tatsächlich durch die komplette Tabelle wühlen muss. Das sind dann garantiert "ein paar" Datenseiten mehr, die ja alle mal kurz im BufferPool Hallo sagen müssen.

    Gruß Dirk


    May you never suffer the sentiment of spending a day without any purpose

    Donnerstag, 17. Oktober 2019 12:48
  • Hallo Jürgen,

    führe doch mal die Diagnostic Querry's für die passende Version auf die relevante Datenbank aus, und stelle doch mal hieraus Informationen, die Aufschluss über Deine Systemumgebung geben, zur Verfügung.

    https://www.sqlskills.com/blogs/glenn/category/dmv-queries/

    Soweit Du in einer VM installiert hast, solltest Du auch mal prüfen:

    -- Check Available CPUs with a SQL Server Query
    -- https://www.mssqltips.com/sqlservertip/4801/sql-server-does-not-use-all-assigned-cpus-on-vm/
    
    SELECT scheduler_id, cpu_id, status, is_online 
    FROM sys.dm_os_schedulers 
    GO
    
    -- Multi Server Query to Check All Servers
    ---------------------------------------------------------------------------------------------------------------
    -- CPU VISIABLE ONLINE CHECK
    ----------------------------------------------------------------------------------------------------------------
    DECLARE @OnlineCpuCount int
    DECLARE @LogicalCpuCount int
    
    SELECT @OnlineCpuCount = COUNT(*) FROM sys.dm_os_schedulers WHERE status = 'VISIBLE ONLINE'
    SELECT @LogicalCpuCount = cpu_count FROM sys.dm_os_sys_info 
    
    SELECT @LogicalCpuCount AS 'ASSIGNED ONLINE CPU #', @OnlineCpuCount AS 'VISIBLE ONLINE CPU #',
       CASE 
         WHEN @OnlineCpuCount < @LogicalCpuCount 
         THEN 'You are not using all CPU assigned to O/S! If it is VM, review your VM configuration to make sure you are not maxout Socket'
         ELSE 'You are using all CPUs assigned to O/S. GOOD!' 
       END as 'CPU Usage Desc'
    ----------------------------------------------------------------------------------------------------------------
    GO
    Schönen Abend.

    Donnerstag, 17. Oktober 2019 18:17
  • Hallo Jürgen,

    ich bin mir relativ sicher, dass es sich bei Deiner Tabelle um einen HEAP oder Clustered Index handelt, der abgefragt wird. Dann - ich rate mal - wirst Du vielleicht auch BLOB-Felder und/oder (basierend auf der Aussage: 170 Attribute) ROW_OVERFLOW-Data haben.

    Wenn Du einen SELECT COUNT[_BIG](*) machst, muss immer die VOLLSTÄNDIGE Tabelle durchsucht werden. Wenn dann Dein System zu wenig Speicher, langsames Storage, … und keine Indexe hat, dann dauert es halt.

    • Welche Indexe hat Deine Tabelle
    • Kannst Du mal den Ausführungsplan Deiner Abfrage posten

    Eine Alternative wäre, dass Du eine Systemtabelle abfragst:

    SELECT	rows
    FROM	sys.partitions
    WHERE	object_id = OBJECT_ID(N'dbo.DeineTable')
    		AND index_id <= 1;


    Uwe Ricken (Blog | Twitter)
    Microsoft Certiifed 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)


    Montag, 11. November 2019 13:11