, elsuket Voici une requête basée sur les vues et fonctions de gestion dynamiques, introduites avec SQL Server 2005.
Elle permet de lister l'ensemble des requêtes actuellement en cours d'exécution dans une instance SQL Server, avec quelques statistiques et caractéristiques :
- le n° de session (SPID),
- le nombre de threads mis en place pour résoudre la requête,
- le nom du serveur,
- le nom du login,
- le pourcentage d'avancement d'une instruction,
- le nom de la base de données,
- le statut de la session,
- le temps écoulé depuis le début de l'exécution,
- le temps CPU consommé,
- le nombre de lectures et d'écritures,
- le type d'instruction,
- le nombre de transactions ouvertes par la session,
- le nombre de resultsets,
- le type d'attente,
- le temps d'attente pour ce type,
- le type d'attente précédent,
- la ressource attendue,
- le nom du programme / job qui exécute la requête,
- l'instruction SQL en cours d'exécution dans le lot,
- le lot SQL complet,
- le plan de requête,
- les hashs de requête et de plan,
- le nombre d'exécutions du plan,
- la date de génération du plan,
- l'adresse IP de la machine exécutant la requête.
Toute suggestion est la bienvenue !
Mise à jour du 13/05/2011
-------------------------------
-- Nicolas SOUQUET - 13/05/2011
-------------------------------
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
;WITH
CTE AS
(
SELECT CASE ES.login_name
WHEN 'NT AUTHORITY\SYSTEM' THEN CASE
WHEN ES.program_name LIKE 'SQLAgent%' THEN 'SQLAgent'
ELSE ES.program_name
END
ELSE ES.login_name
END AS Login
, ES.session_id AS SPID
, ER.blocking_session_id AS BlkBy
, ER.wait_type
, ER.wait_time
, ER.last_wait_type
, COUNT(*) AS Threads
, CAST(ER.percent_complete AS NUMERIC(5,2)) AS percent_complete
, DB_NAME(ER.database_id) AS DB
, UPPER(ER.command) AS Command
, UPPER(ER.status) AS Status
, CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))
END + ':' +
CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))
END + ':' +
CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))
END AS Launched
, ER.cpu_time / 1000 AS CPU
, ER.reads AS Reads
, ER.writes AS Writes
, ER.open_transaction_count AS NbTran
, SUBSTRING
(
ESQLT.text,
ER.statement_start_offset / 2 + 1,
(
CASE
WHEN ER.statement_end_offset = - 1 THEN LEN(CAST(ESQLT.text AS nvarchar(max))) * 2
ELSE ER.statement_end_offset
END - ER.statement_start_offset
) / 2 + 1
) AS StatementInBatch
, ESQLT.text AS Batch
, CASE
WHEN ER.command = 'UPDATE STATISTIC' THEN 'Updating stats on ' + REPLACE(REPLACE(SUBSTRING(ESQLT.text, CHARINDEX('[dbo]', ESQLT.text), CHARINDEX(' ', ESQLT.text, CHARINDEX('[dbo]', ESQLT.text)) - CHARINDEX('[dbo]', ESQLT.text)), '[', ''), ']', '')
END AS info
, CASE
WHEN ES.program_name LIKE 'SQLAgent - TSQL JobStep%' THEN 'Job : ' + J.name
WHEN ES.program_name LIKE 'Microsoft SQL Server Management Studio%' THEN 'SSMS'
WHEN ES.program_name LIKE 'LiteSpeed for SQL Server%' THEN 'LiteSpeed'
WHEN ES.program_name = 'Microsoft SQL Server Analysis Services' THEN 'SSAS'
ELSE ES.program_name
END AS Program
, ES.host_name AS Host
, EC.client_net_address AS IP
, ER.plan_handle
FROM sys.dm_exec_sessions ES (nolock)
INNER JOIN sys.dm_exec_connections (nolock) EC
ON ES.session_id = EC.session_id
INNER JOIN sys.dm_exec_requests ER (nolock)
ON ES.session_id = ER.session_id
LEFT JOIN msdb.dbo.sysjobs J (nolock)
ON REPLACE(SUBSTRING(CAST(J.job_id AS char(36)), CHARINDEX('-', J.job_id, 18) + 1, LEN(J.job_id)), '-', '') =
RIGHT(LEFT(REPLACE(ES.program_name, 'SQLAgent - TSQL JobStep (Job 0x', ''), 32), 16)
CROSS APPLY sys.dm_exec_sql_text(ER.sql_handle) ESQLT
WHERE ES.session_id <> @@SPID
AND ES.is_user_process = 1
AND (J.name NOT LIKE 'cdc%' OR J.name IS NULL)
AND ES.is_user_process = 1
GROUP BY ES.session_id
, ER.blocking_session_id
, ES.host_name
, ES.login_name
, ER.percent_complete
, ER.database_id
, ER.status
, ER.start_time
, ER.cpu_time
, ER.reads
, ER.writes
, ER.command
, ER.open_transaction_count
, ER.statement_start_offset
, ER.statement_end_offset
, ESQLT.text
, ER.wait_type
, ER.wait_time
, ER.last_wait_type
, J.name
, ES.program_name
, EC.client_net_address
, ER.plan_handle
)
SELECT C.Login
, C.SPID
, C.BlkBy
, C.wait_type
, C.wait_time
, C.last_wait_type
, C.Threads
, C.percent_complete AS [%]
, C.DB
, C.Command
, C.Status
, C.Launched
, C.CPU
, C.Reads
, C.Writes
, C.NbTran
, C.StatementInBatch
, C.Batch
, C.info
, C.Program
, C.Host
, C.IP
, C.plan_handle
FROM CTE AS C
ORDER BY C.SPID
-------------------------------
-- Nicolas SOUQUET - 25/06/2010
-------------------------------
SET NOCOUNT ON
;WITH
CTE_THREADS AS
(
SELECT session_id
, COUNT(*) AS nbThreads
FROM sys.dm_exec_sessions
GROUP BY session_id
)
SELECT ES.session_id SPID
, CT.nbThreads
, ER.blocking_session_id BlkBy
, ES.host_name AS Host
, CASE ES.login_name
WHEN 'NT AUTHORITY\SYSTEM' THEN CASE
WHEN ES.program_name LIKE 'SQLAgent%' THEN 'SQLAgent'
ELSE ES.program_name
END
ELSE ES.login_name
END AS Login
, CAST(ER.percent_complete AS NUMERIC(5,2)) AS [%]
, DB_NAME(ER.database_id) AS DB
, UPPER(ER.status) AS Status
, CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))
END + ':' +
CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))
END + ':' +
CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)))
WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))
ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))
END AS Launched
, ER.cpu_time / 1000 AS CPU
, ER.reads AS Reads
, ER.writes AS Writes
, UPPER(ER.command) AS Command
, ER.open_transaction_count NbTran
, ER.open_resultset_count AS NbRsltSet
, ER.wait_type
, ER.wait_time
, ER.last_wait_type
, ER.wait_resource
, CASE
WHEN ES.program_name LIKE 'SQLAgent - TSQL JobStep%' THEN 'Job : ' + J.name
WHEN ES.program_name LIKE 'Microsoft SQL Server Management Studio%' THEN 'SQL Qry'
ELSE ES.program_name
END AS Program
, SUBSTRING(
ESQLT.text,
ER.statement_start_offset / 2 + 1,
(
CASE
WHEN ER.statement_end_offset = - 1 THEN LEN(CAST(ESQLT.text AS nvarchar(max))) * 2
ELSE ER.statement_end_offset
END - ER.statement_start_offset
) / 2
) AS StatementInBatch
, ESQLT.text AS Batch
, QP.query_plan
, ER.query_hash
, ER.query_plan_hash
, QS.execution_count
, QS.creation_time
, EC.client_net_address AS IP
FROM sys.dm_exec_sessions ES (nolock)
INNER JOIN sys.dm_exec_connections (nolock) EC
ON ES.session_id = EC.session_id
INNER JOIN sys.dm_exec_requests ER (nolock)
ON ES.session_id = ER.session_id
INNER JOIN CTE_THREADS AS CT
ON ES.session_id = CT.session_id
LEFT JOIN msdb.dbo.sysjobs J (nolock)
ON REPLACE(SUBSTRING(CAST(J.job_id AS CHAR(36)), CHARINDEX('-', J.job_id, 18) + 1, LEN(J.job_id)), '-', '') =
RIGHT(LEFT(REPLACE(ES.program_name, 'SQLAgent - TSQL JobStep (Job 0x', ''), 32), 16)
CROSS APPLY sys.dm_exec_sql_text(ER.sql_handle) ESQLT
OUTER APPLY sys.dm_exec_query_plan (ER.plan_handle) AS QP
LEFT JOIN sys.dm_exec_query_stats AS QS
ON ER.plan_handle = QS.plan_handle
WHERE ES.session_id <> @@SPID
AND (J.name IS NULL OR J.name NOT LIKE 'cdc.%')
ORDER BY ES.session_id
ElSüket
Vous devez être identifié pour poster un commentaire.
ElSüket
| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Après avoir vu ce que sont la fragmentation interne et externe d'un index, voyons les différences entre les options REBUILD et REORGANIZE de l'instruction ALTER INDEX (ou respectivement DBCC DBREINDEX ou DBCC INDEXDEFRAG sous SQL Server 2000)
]suite
Quand on parle de la fragmentation physique des indexes, on parle aussi de fragmentation externe. Celle-ci se "produit" lorsque l'ordre logique des pages de l'index est incorrect. Les nouvelles valeurs de clé de l'index sont alors insérées dans de nouvelles pages d'index, qui désordonnent l'ordre original de la clé de l'index.
Quand on parle de fragmentation logique de l'index, on parle aussi de fragmentation interne : c'est le cas lorsque la quantité de données stockée dans les pages de l'index est plus petite que la quantité maximale de données que peut stocker une page.
ElSuket
Voici une requête qui nous permet de retrouver pour tout index :
- la liste de ses colonnes clé
- la liste de ses colonnes incluses
- la définition de son filtre
- le script de création de cet index
Voici une petite requête qui permet de lister les colonnes de tous les index d'une base de données, avec leur type et l'ordre des colonnes dans la clé de l'index :
]suite
Il est possible qu'un jour vous trouviez dans les journaux de SQL Server le libellé suivant :
SQL Server has encountered n occurrence(s) of cachestore flush for the (partie du cache de plans) cachestore due to some database maintenance or reconfigure operations"
Ce message n'apparaît qu'à partir du SP2 de SQL Server 2005, et il est écrit par intervalles de 5 minutes.
La purge du cache de plans peut se produire dans les cas suivants :
]suite
Une nouvelle fonctionnalité intéressante, introduite avec SQL Server 2005, est la recherche d’indexes manquants.
Elle permet, de façon très simple, de trouver les indexes manquants qui pourraient simplifier le travail
du moteur de base de données s’ils étaient posés sur des tables de base ou des vues indexées.
Néanmoins, cette fonctionnalité comporte quelques limitations, qui doivent être prise en compte avant qu’on
ait décidé de créer l’index conseillé par SQL Server.
Comme vous le verrez, plusieurs sujets sont connexes à cet article, mais nous ne les aborderons pas ici.
Ils seront l’objet de prochains articles.
Si les index représentent l'optimisation la plus simple à mettre en place, on souhaite néanmoins conserver le minimum d'entre-eux, car leur maintenance lors de l'exécution de requêtes de modifications de données (INSERT, UPDATE, DELETE) peut être coûteuse, surtout sur des tables volumineuses.
Voyons comment collecter cette information ...
]suite
Voici une petite procédure stockée qui permet de connaître l'état physique des index (nombre de pages du niveau feuille, fragmentation et taux d'utilisation des pages) en même temps que la façon dont ils sont utilisés (nombres de seeks et de scans, ...).
Elle est utilisable pour collecter ces statistiques sur l'ensemble d'une base de données, ou bien sur une table en particulier
]suite
Voici une petite procédure stockée que l'on peut exécuter régulièrement dans un job pour défragmenter les indexes de toutes les bases de données, en fixant les seuils de nombre de page et de pourcentage moyen de fragmentation
Outre sa principale fonctionnalité de gestion d'exécutions, l'Agent SQL Server comporte quelques fonctionnalités intéressantes concernant la gestion de son historique.
]suite
S'il est une valeur intéressante à suivre pour le performances d'un serveur, c'est bien le Buffer Cache Hit Ratio, ou Taux d'accès au cache des tampons, car celui-ci est un rapport du nombre de pages lues en RAM par rapport au nombre de pages lues à partir des disques.
Voici une petite requête pour trouver sa valeur :
Voici une procédure stockée pour :
- vérifier une adresse IP
- chercher si celle-ci est privée
- chercher la classe de cette adresse IP
Nous allons voir comment on peut exécuter n'importe quelle procédure stockée dès le démarrage de SQL Server, à l'aide de la procédure stockée sp_procoption
Il est souvent demandé s'il est possible de concaténer les valeurs d'une colonne dans une variable, éventuellement en les séparant avec un symbole de ponctuation.
Voici comment faire, sans curseur ni expression de table commune ...
]suite
Comment connaître simplement l'état d'un service ?
Est-il possible d'arrêter et de démarrer un service avec une requête ?
Voici une petite requête qui permet de voir toutes les restaurations de bases de données d'une instance ...
Pourquoi ne pas créer une table de dates pour se faciliter les recherches dans des tables suivant la colonne de type date qu'elles contiennent ?
On peut vous demander par exemple de rechercher la quantité d'eau consommée par un parc de machines pour la deuxième semaine de chaque mois d'une année.
Imaginez un peu la complexité de la requête à écrire ...
Voyons comment on peut résoudre cette demande très facilement en créant une table de dates ...
Certains me désignent sur le forum SQL Server comme l'homme qui murmure à l'oreille des CTE.
En voici donc une nouvelle !
Voici une petite fonction qui permet de vérifier la présence d'un caractère qui n'est pas supporté par la norme ASCII dans une chaîne de caractères ...
Voici quelques exemples simples de code qui montrent que sous SQL Server 2008, on peut non seulement se passer des sempiternelles deux lignes de code nécessaires jusqu'en version 2005 pour déclarer et affecter d'un valeur une variable, mais on peut aller encore plus loin ...
Copyright © 2000-2012 - www.developpez.com