J'ai gardé un journal des requêtes en cours d'exécution coûteuses, ainsi que leurs plans de requête, dans un tableau pour nous permettre de surveiller les tendances de performances et d'identifier les domaines qui doivent être optimisés.
Cependant, il est arrivé au point où les plans de requête prennent trop de place (car nous stockons le plan entier pour chaque requête).
J'essaie donc de normaliser les données existantes en extrayant QueryPlanHash et QueryPlan vers une autre table.
CREATE TABLE QueryPlans
(
QueryPlanHash VARBINARY(25),
QueryPlan XML,
CONSTRAINT PK_QueryPlans PRIMARY KEY
(
QueryPlanHash
)
);
Comme la définition du query_plan_hash
dans sys.dm_exec_query_stats
est un champ binaire (et j'insérerai régulièrement de nouvelles données), j'utilisais VARBINARY
pour le type de données dans ma nouvelle table.
Cependant, l'encart ci-dessous échoue ...
INSERT INTO QueryPlans
( QueryPlanHash, QueryPlan )
SELECT queryplanhash, queryplan
FROM
(
SELECT
p.value('(./@QueryPlanHash)[1]', 'varchar(20)') queryplanhash,
QueryPlan,
ROW_NUMBER() OVER (PARTITION BY p.value('(./@QueryPlanHash)[1]', 'varchar(20)') ORDER BY DateRecorded) rownum
FROM table
CROSS APPLY QueryPlan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple[@QueryPlanHash]') t(p)
) data
WHERE rownum = 1
.... avec l'erreur
Implicit conversion from data type varchar to varbinary is not allowed. Use the CONVERT function to run this query.
Le problème est que les hachages du plan de requête sont déjà au format binaire, cependant stockés en tant que VARCHAR dans le plan de requête XML, par exemple.
0x9473FBCCBC01AFE
et CONVERT en BINARY donne une valeur complètement différente
0x3078393437334642434342433031414645
J'ai essayé de changer la définition de valeur dans la sélection XQuery en binaire, mais il n'a renvoyé aucune valeur.
Comment extraire la valeur de 0x9473FBCCBC01AFE
à partir d'un plan de requête XML en tant que VARBINARY
, plutôt que VARCHAR
?
Vous devez utiliser un style spécifique lorsque vous prévoyez de conserver la même valeur binaire lors de la conversion à partir d'une chaîne. Sinon, SQL Server essaie de coder la chaîne de la même manière qu'il coderait 'bob'
ou 'frank'
.
Cela dit, votre chaîne d'entrée ne semble pas correcte - il y a soit un octet manquant, soit un octet de trop. Cela fonctionne très bien si je laisse tomber le E
de fin:
SELECT CONVERT(VARBINARY(25), '0x9473FBCCBC01AF', 1);
------------ the ,1 is important ---------------^^^
Le résultat est binaire:
----------------
0x9473FBCCBC01AF
Comment extraire la valeur de 0x9473FBCCBC01AFE d'un plan de requête XML en tant que VARBINARY, plutôt que VARCHAR?
J'ai fait face à quelque chose comme ça en utilisant HeidiSQL pour interroger les tables CASD, et j'ai résolu avec fn_varbintohexstr (), comme ceci:
SELECT master.dbo.fn_varbintohexstr(table.hexfield) FROM table;
Avec HeidiSQL, la valeur était incorrecte comme '0x3F3F3F3F3F3F3F3F' et est devenue correcte comme '0x158B1DB75616484695684007CE98E21C'.
OBS: Fonctionne depuis MSSQL 2008! J'espère que cela aide!