Ieri in "[NHibernate] e l'importanza dei parametri precisi!" avevo sollevato il problema della difficoltà nel definire correttamente i parametri stringa in NHibernate... leggendo meglio la documentazione ho scoperto l'esistenza di tipi built-in già pronti - beh avrei dovuto sospettarlo che non potevano aver trascurato un problema simile.
Tornando quindi all'esempio di ieri la corretta definizione del nostro campo CHAR(5) è la seguente:
<ID column="CODICE" name="Codice" type="AnsiString(5)"><GENERATOR class=assigned /></ID>
Quindi riassumendo:
- Se si ha una colonna CHAR(n) o VARCHAR(n) dove n > 1 occorre definire esplicitamente il type AnsiString(n). Se abbiamo un CHAR(1) possiamo usare AnsiChar;
- Se si ha una colonna NCHAR(n) o NVARCHAR(n) dove n > 1 occorre definire il type String(n). Se abbiamo un NCHAR(1) possiamo usare Char. Se la proprietà è stringa "String" è il valore di default quindi è da usare esplicatemente se vogliamo specificarne la lunghezza.
Vediamo di fare un esempio.
CREATE TABLE [dbo].[Sheet1$]
(
[Codice] [char](5) NOT NULL,
[Descrizione] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_Sheet1$] PRIMARY KEY CLUSTERED ([Codice] ASC)
)
Riempiamo le tabella con qualche migliaio di elementi e facciamo qualche query controllando l'execution plan.
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0',
N'@p0 nvarchar(5)',
@p0 = N'90001'
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0',
N'@p0 varchar(5)',
@p0 = '90001'
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0',
N'@p0 char(5)',
@p0 = '90001'
Che sono verosimilmente quelle eseguite da NHIbernate usando il paramentro @P definito prima String - Unicode - e poi AnsiString - ANSI.
Come si vede in un caso viene eseguito uno SCAN sull'indice... nel secondo caso viene fatto una più performante SEEK, rimando a "scan VS seek" la spiegazione dei due predicati di ricerca. La cosa interssante è che il PLANNING NON VARIA se definiamo la lunghezza del parametro non precisa - esempio "@p VARCHAR(4000)" - ... l'importante quindi è definire correttamente il tipo. Beh tutto bene quel che finisce bene!
posted @ sabato 20 gennaio 2007 00:14