Was passiert im SQL-Server eigentlich wenn man den Datenbankordner aufklickt?

Diese Frage hat sich sicher bestimmt schon jeder gefragt. Mal dauert es länger und mal geht es wirklich schnell.

Warum dauert das Öffnen des Datenbankorders viel länger wie das öffnen des DropDowns im Menüband?
Woran liegt das?
Kann man das öffnen des Datenbankordners optimieren?
Genau vor diesen Fragen bin ich auch gestanden. Im Web habe ich leider keine befriedigende Antwort auf die gestellten Fragen bekommen. Also habe ich mich auf die Ursachenforschung begeben.

Wie stellt man aber eine solche Nachforschung an?

Testumgebung für Analyse expandieren vom Datenbankordner

Ich bin ganz pragmatisch an die Sache ran gegangen. Als erstes habe ich mir ein Test-System mit einem SQL Server 2014 Standard-Edition (Trail) installiert. Mit einem Script habe ich mir 150 leere Test-Datenbanken angelegt. Der gewünschte und erhofte Effekt, dass das Öffnen vom Datenbankordner im SQL-Server Management-Studio länger dauert blieb leider aus.

Datenbankorder geöffnet
Datenbankorder geöffnet

Analyse

Als nächstes habe ich die Ablaufverfolgung gestartet. Bei laufender Ablaufverfolgung habe ich dann wieder den Datenbankordner geöffnet. Das Ergebnis der Ablaufverfolgung war für mich etwas verwunderlich.

Als erstes für der SQL-Server die folgenden Scripte aus.

exec sp_executesql N'
        create table #tmp_db_hadr_dbrs (group_database_id uniqueidentifier, synchronization_state tinyint, is_local bit)
      
        declare @HasViewPermission int
        select @HasViewPermission = HAS_PERMS_BY_NAME(null, null, ''VIEW SERVER STATE'')
      
        if (@HasViewPermission = 1)
        begin
        insert into #tmp_db_hadr_dbrs select group_database_id, synchronization_state, is_local from master.sys.dm_hadr_database_replica_states
        end

SELECT
dtb.name AS [Database_Name],
''Server[@Name='' + quotename(CAST(
        serverproperty(N''Servername'')
       AS sysname),'''''''') + '']'' + ''/Database[@Name='' + quotename(dtb.name,'''''''') + '']'' AS [Database_Urn],
dtb.containment AS [Database_ContainmentType],
dtb.recovery_model AS [Database_RecoveryModel],
ISNULL(suser_sname(dtb.owner_sid),'''') AS [Database_Owner],

          case
          when dtb.collation_name is null then 0x200
          else 0
          end |
          case
          when 1 = dtb.is_in_standby then 0x40
          else 0
          end |
          case dtb.state
          when 1 then 0x2
          when 2 then 0x8
          when 3 then 0x4
          when 4 then 0x10
          when 5 then 0x100
          when 6 then 0x20
          else 1
          end
         AS [Database_Status],
dtb.compatibility_level AS [Database_CompatibilityLevel],
ISNULL(dmi.mirroring_role,0) AS [Database_MirroringRole],
ISNULL(dmi.mirroring_state + 1, 0) AS [Database_MirroringStatus],
CAST(has_dbaccess(dtb.name) AS bit) AS [Database_IsAccessible],
dbrs.synchronization_state AS [Database_AvailabilityDatabaseSynchronizationState],
0 AS [Database_HasMemoryOptimizedObjects],
dtb.recovery_model AS [RecoveryModel],
dtb.user_access AS [UserAccess],
dtb.is_read_only AS [ReadOnly],
dtb.name AS [Database_DatabaseName2],
dtb.name AS [Database_DatabaseName3]
FROM
master.sys.databases AS dtb
LEFT OUTER JOIN sys.database_mirroring AS dmi ON dmi.database_id = dtb.database_id
LEFT OUTER JOIN #tmp_db_hadr_dbrs AS dbrs ON dtb.group_database_id = dbrs.group_database_id and dbrs.is_local = 1

WHERE
(CAST(case when dtb.name in (''master'',''model'',''msdb'',''tempdb'') then 1 else dtb.is_distributor end AS bit)=@_msparam_0 and CAST(isnull(dtb.source_database_id, 0) AS bit)=@_msparam_1)
ORDER BY
[Database_Name] ASC
        
        drop table #tmp_db_hadr_dbrs
      
',N'@_msparam_0 nvarchar(4000),@_msparam_1 nvarchar(4000)',@_msparam_0=N'0',@_msparam_1=N'0'

Als ich die Duration (s. Bild 1) dieses Scriptes gesehen habe hatte ich noch mehr Fragezeichen im Kopf als vorher.

Profiler-Ergebnis Datenbankordner öffnen
Profiler-Ergebnis Datenbankordner öffnen

Die weitere Analyse ergab, dass pro registrierter Datenbank das folgende Script ausgeführt wird.

use <<DATABASE>>
SELECT
ISNULL((select top 1 1 from sys.filegroups FG where FG.[type] = 'FX'), 0) AS [HasMemoryOptimizedObjects]

Die Duration (s. Bild 2) ist von Datenbank zu Datenbank unterschiedlich und das obwohl alle Datenbanken bis auf den Datenbanknamen identisch sind.

Laufzeitergebnis der Abfrage für jede registierte Datenbank
Laufzeitergebnis der Abfrage für jede registierte Datenbank

Ergebnis

Aufgrund dieser Untersuchung kann ich zwar sagen, dass die Dauer für das Öffnen vom Datenbankordner im Management Studio von der Anzahl der registrierten Datenbanken abhängt aber warum die Werte von Datenbank zu Datenbank so extrem schwanken ist mir weiterhin ein Rätsel. Eine leichte Beschleunigung für das Öffnen des Datenbankorders hat die Konfiguration und Optimierung der TempDB gebracht.

Ich bleibe der Sache aber weiter auf der Spur.

Von Michael