> [!TIP] > Recept z [kuchárky exekučných plánov](script.php?id=64&s=exekucne-plany-kucharka-zacni-tu). Ukážky bežia v testovacej databáze [PlanLab](script.php?id=65&s=planlab-testovacia-databaza-pre-recepty-exekucnych-planov) – nikdy ich nespúšťaj na produkcii. ## Ako to vyzerá v pláne  V *Predicate* alebo *Seek Predicates* vidíš **CONVERT_IMPLICIT(…)** okolo **stĺpca** a na SELECT žltý trojuholník s varovaním *Type conversion in expression (CONVERT_IMPLICIT(…)) may affect "CardinalityEstimate"* alebo *"SeekPlan" in query plan choice*. ## Čo to znamená Keď porovnávaš dve hodnoty rôznych typov, SQL Server jednu prevedie na typ druhej podľa **priority dátových typov** (*data type precedence*). `nvarchar` má vyššiu prioritu ako `varchar`, takže pri `WHERE AccountCode = N'AC000123'` (alebo parameter `nvarchar` z aplikácie) sa prevádza **stĺpec** – v každom riadku. Index na stĺpci potom nejde použiť obvyklým spôsobom a odhad je horší. ### Do hĺbky - Najčastejšie páry: `varchar` stĺpec vs. `nvarchar` parameter (ORM, .NET reťazce sú predvolene nvarchar), `int` stĺpec vs. `varchar` hodnota, `date` vs. `datetime2`, rôzne kolácie. - Pri **Windows kolácii** (napr. `Latin1_General_CI_AS`) vie SQL Server aj s konverziou urobiť seek cez rozsah (*GetRangeThroughConvert*, v pláne Compute Scalar + Constant Scan + Nested Loops pred seekom) – odhad je však horší. Pri **SQL kolácii** (`SQL_Latin1_General_CP1_CI_AS`) skončí `varchar` stĺpec s `nvarchar` hodnotou **skenom**. - Konverzia **parametra** (nie stĺpca) je v poriadku – napr. `int` stĺpec a `smallint` parameter. - Varovanie *may affect CardinalityEstimate* sa objavuje aj pri konverziách v SELECT zozname, kde nevadí – rozhodujúce je, či je konverzia na stĺpci vo WHERE / JOIN. ## Kedy je to v poriadku / kedy problém | V poriadku | Problém | |---|---| | konverzia konštanty alebo parametra | CONVERT_IMPLICIT na stĺpci vo WHERE / JOIN | | varovanie pri výraze vo výstupe | sken veľkej tabuľky, hoci index na stĺpci existuje | ## Ako si to vyskúšať ```sql USE PlanLab; SET STATISTICS IO ON; -- 1) Správny typ (varchar) → Index Seek SELECT OrderID FROM dbo.Orders WHERE AccountCode = 'AC000123'; -- 2) nvarchar konštanta → CONVERT_IMPLICIT na stĺpci (podľa kolácie seek cez rozsah alebo sken) SELECT OrderID FROM dbo.Orders WHERE AccountCode = N'AC000123'; -- 3) Tak to robí aplikácia: nvarchar parameter EXEC sys.sp_executesql N'SELECT OrderID FROM dbo.Orders WHERE AccountCode = @p', N'@p nvarchar(20)', @p = N'AC000123'; -- 4) Oprava na strane volajúceho: správny typ parametra EXEC sys.sp_executesql N'SELECT OrderID FROM dbo.Orders WHERE AccountCode = @p', N'@p varchar(20)', @p = 'AC000123'; -- kolácia databázy SELECT DATABASEPROPERTYEX(N'PlanLab', 'Collation') AS kolacia; ``` Spusti s **Include Actual Execution Plan** (Ctrl+M), pri bodoch 2 a 3 nájdi varovanie na SELECT a *Predicate* / *Seek Predicates* s CONVERT_IMPLICIT. ## Čo s tým 1. **Oprav typ na strane volajúceho**: parameter rovnakého typu a dĺžky ako stĺpec (v .NET `SqlDbType.VarChar`, v ORM mapovanie stĺpca ako ansi / `varchar`). 2. V T-SQL: premenné a parametre deklaruj typom stĺpca; konštanty pre varchar stĺpce píš bez `N` prefixu. 3. Ak sa volajúci zmeniť nedá: zváž zmenu typu stĺpca (dlhodobé riešenie, pozor na veľkosť a závislosti) alebo computed column s indexom. 4. Hľadaj konverzie v cache: plány s textom `CONVERT_IMPLICIT` (napr. cez [Top 20 dotazov podľa CPU](script.php?id=5&s=top-20-dotazov-podla-cpu) a XML plánu). ## Súvisiace - [Non-SARGable podmienky](script.php?id=89&s=non-sargable-podmienky-funkcia-na-stlpci-like-x-or) - [Index Seek – seek vs. residual predicate](script.php?id=69&s=index-seek-seek-predicate-vs-residual-predicate) - [Varovania v pláne](script.php?id=96&s=varovania-v-plane-zlty-trojuholnik-no-join-predicate-no-statistics) - [Table Scan a Clustered Index Scan](script.php?id=68&s=table-scan-a-clustered-index-scan-citanie-celej-tabulky) ## Zdroje - [Microsoft Learn – Data type precedence](https://learn.microsoft.com/sql/t-sql/data-types/data-type-precedence-transact-sql) - [Microsoft Learn – Data type conversion (Database Engine)](https://learn.microsoft.com/sql/t-sql/data-types/data-type-conversion-database-engine) - [Paul White – SQLkiwi (články o optimalizátore a operátoroch)](https://www.sql.kiwi/) - [Brent Ozar – blog a nástroje First Responder Kit](https://www.brentozar.com/) _Texty sú vlastné, tvrdenia overené proti uvedeným zdrojom (11/2026). T-SQL je staticky skontrolovaný, nie spustený na živom serveri – vyskúšaj ho najprv v PlanLab._
Implicitná konverzia (CONVERT_IMPLICIT) – varchar vs. nvarchar
CONVERT_IMPLICIT v pláne: priorita dátových typov, varchar stĺpec a nvarchar parameter, varovanie SeekPlan / CardinalityEstimate, vplyv kolácie a ako typy zosúladiť.