{"id":274,"date":"2011-03-20T00:00:02","date_gmt":"2011-03-20T00:00:02","guid":{"rendered":"http:\/\/www.sqlserver.fr\/blog\/?p=274"},"modified":"2026-05-02T14:31:23","modified_gmt":"2026-05-02T12:31:23","slug":"conversion-implicite","status":"publish","type":"post","link":"https:\/\/www.sqlserver.fr\/blog\/conversion-implicite\/","title":{"rendered":"Conversion Implicite"},"content":{"rendered":"<p style=\"text-align: left;\"><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image001.gif\"><br \/>\n<\/a>Un aspect souvent mal per\u00e7u entra\u00eenant une d\u00e9gradation des performances r\u00e9side dans la conversion implicite des donn\u00e9es. Voici une petite d\u00e9monstration de la chose, qui montre que malgr\u00e9 un index sur la bonne colonne, les performances peuvent parfois ne pas correspondre \u00e0 celles attendues.<!--more--><br \/>\nLe tableau ci-dessous (extrait de l\u2019aide en ligne de SQL Server, <a href=\"https:\/\/docs.microsoft.com\/fr-fr\/sql\/t-sql\/functions\/cast-and-convert-transact-sql\">https:\/\/docs.microsoft.com\/fr-fr\/sql\/t-sql\/functions\/cast-and-convert-transact-sql<\/a>) montre les diff\u00e9rentes conversions explicites et implicites entre types de donn\u00e9es sous SQL Server.<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image001.gif\"><img loading=\"lazy\" decoding=\"async\" title=\"image001\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image001.gif\" alt=\"\" width=\"620\" height=\"669\" \/><\/a><\/p>\n<p>Nous nous appuierons ici sur la conversion entre le type int et varchar.<br \/>\nCr\u00e9ons une table contenant par exemple une liste de clients.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">use tempdb\r\ngo\r\ncreate table Clients\r\n\t(Id_Technique int identity primary key,\r\n\tCode_Client varchar(50),\r\n\tNom_Client varchar(100),\r\n\tDate_Creation datetime)\r\ngo\r\ndeclare @i int=0\r\nwhile @i&lt;100000\r\nbegin\r\n\tselect @i+=1\r\n\tinsert into Clients\r\n\t\t(Code_Client, Nom_Client, Date_Creation)\r\n\t\tselect\r\n\t\t@i, 'Client N\u00b0' + convert(varchar,@i), getdate()\r\nend<\/pre>\n<p>Parmi les 10 000 clients que nous avons ins\u00e9r\u00e9s dans la table, cherchons par exemple celui dont le code est 1234.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">select * from Clients where Code_Client=1234<\/pre>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image002.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-277\" title=\"image002\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image002.png\" alt=\"\" width=\"420\" height=\"73\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image002.png 420w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image002-300x52.png 300w\" sizes=\"auto, (max-width: 420px) 100vw, 420px\" \/><\/a><\/p>\n<p>Cela semble tr\u00e8s bien, mais en regardant le plan d\u2019ex\u00e9cution, on remarque que le moteur de donn\u00e9es est oblig\u00e9 de parcourir toute la table \u00e0 la recherche du bon client.<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0031.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-278\" title=\"image003\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0031.png\" alt=\"\" width=\"462\" height=\"151\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0031.png 462w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0031-300x98.png 300w\" sizes=\"auto, (max-width: 462px) 100vw, 462px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image004.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-279\" title=\"image004\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image004.png\" alt=\"\" width=\"593\" height=\"200\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image004.png 593w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image004-300x101.png 300w\" sizes=\"auto, (max-width: 593px) 100vw, 593px\" \/><\/a><\/p>\n<p>Du point de vue des ressources consomm\u00e9es, on obtient 568 lectures logiques pour trouver notre enregistrement, c\u2019est-\u00e0-dire 568 pages de 8Ko ! C\u2019est tout de m\u00eame un peu exag\u00e9r\u00e9 pour une recherche qui parait tr\u00e8s basique.<br \/>\nR\u00e9ponse imm\u00e9diate : mettons un index sur la colonne Code_Client, et \u00e7a devrait (a priori) mieux fonctionner.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">create index IX_Code_Client on Clients(Code_Client)<\/pre>\n<p>Et maintenant, \u00e7a donne quoi ?<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0051.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-280\" title=\"image005\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0051.png\" alt=\"\" width=\"443\" height=\"197\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0051.png 443w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image0051-300x133.png 300w\" sizes=\"auto, (max-width: 443px) 100vw, 443px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image006.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-281\" title=\"image006\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image006.png\" alt=\"\" width=\"555\" height=\"239\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image006.png 555w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image006-300x129.png 300w\" sizes=\"auto, (max-width: 555px) 100vw, 555px\" \/><\/a><\/p>\n<p>Ca a l\u2019air un peu mieux, on passe par le fameux nouvel index, mais on se retrouve encore avec 239 lectures, dues \u00e0 un parcours complet de notre liste de codes client au lieu de justement utiliser pleinement l\u2019index pour trouver tr\u00e8s rapidement le num\u00e9ro exact demand\u00e9. Que s\u2019est-il pass\u00e9 ?<br \/>\nLa solution apparait en regardant de plus pr\u00eat les d\u00e9tails de cet Index Scan.<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image007.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter  wp-image-282\" title=\"image007\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image007.png\" alt=\"\" width=\"620\" height=\"410\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image007.png 743w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image007-300x198.png 300w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p>On y voit une conversion implicite. Qu\u2019est-ce que c\u2019est que cette b\u00eate ? Et bien, tout simplement, notre code client est stock\u00e9 sous forme de cha\u00eene de caract\u00e8res (varchar(50)), et nous recherchons un code client exprim\u00e9 sous forme num\u00e9rique. Dans ce cas, le moteur effectue la conversion sous forme num\u00e9rique, et doit donc convertir sous forme num\u00e9rique chacun des codes clients qui se pr\u00e9sentent \u00e0 lui.<br \/>\nOn arrive donc \u00e0 la solution du probl\u00e8me pour enfin optimiser cette fichue requ\u00eate :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">select * from Clients where Code_Client='1234'<\/pre>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image008.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-283\" title=\"image008\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image008.png\" alt=\"\" width=\"429\" height=\"151\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image008.png 429w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image008-300x105.png 300w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image009.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-284\" title=\"image009\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image009.png\" alt=\"\" width=\"556\" height=\"234\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image009.png 556w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image009-300x126.png 300w\" sizes=\"auto, (max-width: 556px) 100vw, 556px\" \/><\/a><\/p>\n<p>Nous obtenons enfin un joli Index Seek, qui nous donne au final un requ\u00eate ne co\u00fbtant que 4 lectures logiques, c\u2019est-\u00e0-dire seulement 32Ko.<\/p>\n<p>Accessoirement, un autre cas particuliers aurait pu nous obliger tout simplement \u00e0 exprimer correctement le code client recherch\u00e9 (c&rsquo;est-\u00e0-dire sous forme de type de donn\u00e9es correspondant \u00e0 celui de la colonne utilis\u00e9e pour le stockage\u2026) :<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image010.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter  wp-image-285\" title=\"image010\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image010.png\" alt=\"\" width=\"620\" height=\"138\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image010.png 770w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/03\/image010-300x66.png 300w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p>Mais quand on fait quelque chose par obligation pour se d\u00e9bloquer, c\u2019est toujours moins int\u00e9ressant que d\u2019avoir quelque chose qui marche tant bien que mal et que l\u2019on peut prendre le temps de chercher \u00e0 optimiser\u2026<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un aspect souvent mal per\u00e7u entra\u00eenant une d\u00e9gradation des performances r\u00e9side dans la conversion implicite des donn\u00e9es. Voici une petite d\u00e9monstration de la chose, qui montre que malgr\u00e9 un index sur la bonne colonne, les performances peuvent parfois ne pas &hellip; <a href=\"https:\/\/www.sqlserver.fr\/blog\/conversion-implicite\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-274","post","type-post","status-publish","format-standard","hentry","category-article_sql"],"_links":{"self":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/274","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/comments?post=274"}],"version-history":[{"count":26,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/274\/revisions"}],"predecessor-version":[{"id":1968,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/274\/revisions\/1968"}],"wp:attachment":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/media?parent=274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/categories?post=274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/tags?post=274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}