Visual Expert monitoriza el rendimiento de su código Transact-SQL y produce análisis sobre su ejecución. Esto ayuda a los desarrolladores de T-SQL a ajustar el rendimiento de su código.
Esta funcionalidad se basa en los datos de ejecución del código que su base de datos generará, y que usted cargará en su proyecto Visual Expert. Visual Expert combinará entonces estos datos con la información extraída durante el análisis estático de su código.
La generación de estos datos de ejecución del código depende de su configuración:
bcp "exec [{DataBaseName}].[{schema}].[WritePerformanceDataToFile] @databaseName = N'{DatabaseName1,DatabaseName2,...}', @recordsLimit = {NULL|any number}" queryout "{output file full path}.VETSQLPERF" -w {-T|-U "{username}" -P "{password}"} -S "{server\instance}"
Esto ejecutará el procedimiento almacenado - WritePerformanceDataToFile y escribirá el resultado en un archivo.
bcp "exec [MyDb].[dbo].[WritePerformanceDataToFile] @databaseName = N'SalesDB, TestDB', @recordsLimit = NULL" queryout "D:\VEPerformanceFiles\MultipleDB.VETSQLPERF" -w -T
bcp "exec [MyDb].[dbo].[WritePerformanceDataToFile] @databaseName = N'TestDB', @recordsLimit = NULL" queryout "D:\VEPerformanceFiles\SingleDB.VETSQLPERF" -w -T
bcp "exec [MyDb].[dbo].[WritePerformanceDataToFile] @databaseName = N'TestDB', @recordsLimit = 10000" queryout "D:\VEPerformanceFiles\SingleDB.VETSQLPERF" -w -T
bcp "exec [MyDb].[dbo].[WritePerformanceDataToFile] @databaseName = N'TestDB', @recordsLimit = NULL" queryout "D:\VEPerformanceFiles\SingleDB.VETSQLPERF" -w -U " TEST" -P "test user password" -S "server\SQL-Server-instance"
bcp "exec [MyDb].[dbo].[WritePerformanceDataToFile] @databaseName = N'SalesDB, TestDB', @recordsLimit = NULL" queryout "D:\VEPerformanceFiles\MultipleDB.VETSQLPERF" -w -U "TEST" -P "test user password" -S "server\ SQL-Server-instance"
Por ejemplo:
@databaseName = N'{DatabaseName1,DatabaseName2}' -- multiple databases
O
@databaseName = N'{DatabaseName1}' -- single database
Por ejemplo:
@recordsLimit = NULL -- all records will be read and written to output file
O
@recordsLimit = 10000 -- maximum 10000 records will be read and written to output file
Nota:Asegúrese que el directorio existe en la ruta del archivo, de lo contrario bcp mandara un error.
Por ejemplo:
queryout "D:\VEPerformanceFiles\alldatabase.VETSQLPERF"
O
queryout "D:\VEPerformanceFiles\SalesDB.VETSQLPERF"
Por ejemplo:
For "sa" USER -U "sa"
Nota: Para conectar al SQL Server con una conexión de confianza usando seguridad integrada, el usuario puede escribir -T en lugar de -U y -P
Ejemplos:
-S "(local)\SQLExpress"
-S "DB-SERVER1\SQLSERVER2019"
Para más detalles sobre el uso de bcp, por favor consulte: https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-ver15
bcp "exec [TestDatabase].[dbo].[WritePerformanceDataToFile] @databaseName = N'TestDB1', @recordsLimit = NULL" queryout "D:\VEPerformanceFiles\SingleDB.VETSQLPERF" -w -U "SA" -P "testpassword" -S "(local)"
GRANT VIEW SERVER STATE to {user} USE master GO GRANT VIEW SERVER STATE TO test;
GRANT EXECUTE ON {database}.{schema}.[WritePerformanceDataToFile] to {user}; Use {database} Go GRANT EXECUTE to [test];
Captura de pantalla de la ejecución exitosa:
Una vez que el archivo de rendimiento esté listo, puede ser analizado por Visual Expert. Sigue los pasos siguientes:
==================== Fuente del archivo VEPerfUtils_TSQL.SQL =========================
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'WritePerformanceDataToFile') DROP PROCEDURE [dbo].[WritePerformanceDataToFile] GO CREATE PROCEDURE [dbo].[WritePerformanceDataToFile] (@databaseName nvarchar(Max), @recordsLimit int = NULL) AS BEGIN Declare @columdelimiter nvarchar(10); Declare @rowdelimiter nvarchar(10); Declare @eventFileFullPath nvarchar(Max) = NULL; Declare @eventName nvarchar(Max); Declare @index int; DECLARE @recordLimitsString varchar(30); DECLARE @SQLString nvarchar(2500); DECLARE @ParmDefinition nvarchar(200); Declare @sliptDelimiter VARCHAR(10) = ','; Declare @dbName nvarchar(Max); Declare @position int; SET @databaseName = CONCAT(@databaseName , @sliptDelimiter); SET @ParmDefinition = N'@recordLimit int, @colum_delimiter nvarchar(10), @row_delimiter nvarchar(10), @eventFilePath nvarchar(260)'; SET @columdelimiter = CONCAT( N'«',N'¬',N'»'); SET @rowdelimiter = CONCAT(N'«',N'®',N'»'); SET @eventName = Concat(N'VE_SQLPerformanceSession', '_', DB_ID(@databaseName)); IF @recordsLimit IS NOT NULL SET @recordLimitsString = 'TOP ' + CAST(@recordsLimit AS VARCHAR(15)) + ' '; ELSE SET @recordLimitsString = ' '; SET @SQLString = 'SELECT ' + @recordLimitsString + ' Concat(ALLRECORDS.duration, @colum_delimiter, ALLRECORDS.sqlFullText, @row_delimiter) as record FROM ' + '(SELECT ' + 'qs.total_elapsed_time/qs.execution_count AS duration, ' + 'SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ' + '((CASE qs.statement_end_offset ' + 'WHEN -1 THEN DATALENGTH(st.text) ' + 'ELSE qs.statement_end_offset ' + 'END - qs.statement_start_offset)/2) + 1) AS sqlFullText ' + 'FROM sys.dm_exec_query_stats AS qs ' + 'CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ' + 'UNION ALL ' + 'SELECT ' + 'qs.total_elapsed_time/qs.execution_count AS duration, ' + 'st.text AS sqlFullText ' + 'FROM sys.dm_exec_procedure_stats AS qs ' + 'CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ' + 'UNION ALL ' + 'SELECT ' + 'ts.total_elapsed_time/ts.execution_count AS duration, ' + 'st.text AS sqlFullText ' + 'FROM sys.dm_exec_trigger_stats AS ts ' + 'CROSS APPLY sys.dm_exec_sql_text(ts.sql_handle) AS st '; SET @position = CHARINDEX(@sliptDelimiter, @databaseName, 0); WHILE @position <> 0 BEGIN SELECT @dbName = RTRIM(LTRIM(SUBSTRING(@databaseName, 1, @position-1))), @databaseName = RTRIM(LTRIM(SUBSTRING(@databaseName, @position + LEN(@sliptDelimiter), LEN(@databaseName)))) SET @dbName = RTRIM(LTRIM(@dbName)); IF LEN(@dbName) > 0 BEGIN IF(Substring(@dbName, 1, 1) = '[' and Substring(@dbName, LEN(@dbName) , LEN(@dbName)) = ']') SET @dbName = Substring(@dbName, 2, LEN(@dbName) - 2) SET @eventName = Concat(N'VE_SQLPerformanceSession', '_', DB_ID(@dbName)); SET @eventFileFullPath = (SELECT TOP 1 cast(f.value as NVARCHAR (Max)) FROM sys.server_event_sessions AS s JOIN sys.server_event_session_targets AS t ON t.event_session_id = s.event_session_id JOIN sys.server_event_session_fields As f ON f.event_session_id = s.event_session_id AND f.object_id = t.target_id WHERE s.name = @eventName); SET @index = CHARINDEX(@eventName, @eventFileFullPath); IF @index > -1 Begin SET @eventFileFullPath = SUBSTRING(@eventFileFullPath, 0, @index); SET @eventFileFullPath = Concat(@eventFileFullPath, @eventName); END IF @eventFileFullPath IS NOT NULL BEGIN SET @SQLString = @SQLString + 'UNION ALL ' + 'SELECT ' + 'CAST(event_Data AS xml).value(''(event/data[@name="duration"]/value)[1]'',''bigint'') AS duration, ' + 'CASE ' + 'WHEN CAST(event_Data AS xml).value(''(event/@name)[1]'', ''varchar(250)'') = ''module_end'' THEN CAST(event_Data AS xml).value(''(event/data[@name="object_name"]/value)[1]'',''nvarchar(250)'') ' + 'Else CAST(event_Data AS xml).value(''(event/data[@name="statement"]/value)[1]'',''nvarchar(MAX)'') ' + 'END AS sqlFullText ' + 'FROM sys.fn_xe_file_target_read_file(CONCAT(@eventFilePath ,''*.xel''), CONCAT(@eventFilePath ,''*.xem''), NULL, NULL) '; END END SET @position = CHARINDEX(@sliptDelimiter, @databaseName, 0); END SET @SQLString = @SQLString + ') AS ALLRECORDS'; EXECUTE sp_executesql @SQLString, @ParmDefinition, @recordLimit = @recordsLimit, @colum_delimiter = @columdelimiter, @row_delimiter = @rowdelimiter, @eventFilePath = @eventFileFullPath; END