giugno 2007 - Posts

SQL Server Best Practices and Performance Tuning for Oracle Enterprise Applications Workshop
27 giugno 07 10.52 | abenedetti | with no comments

Come già scritto da Davide qui, anche io segnalo un evento gratuito su SQL Server ed il suo utilizzo in applicazioni enterprise.

Quando: 10 e l’11 luglio a Zurigo.

Iscrizione qui.

Export tramite bcp e ritorni a capo in colonna
20 giugno 07 10.25 | abenedetti | with no comments

Un piccolissimo suggerimento magari valido per qualcuno...

Necessità: estrarre su file di testo alcune informazioni lette da db
Sopresa: alcune righe andavano a capo in maniera inaspettata

 

Perchè? Perchè chi ha inserito i dati, preso da "copia/incolla" ha portato in tabella anche i ritorni a capo.

 

Quindi mi è stato chiesto: come posso eliminarli dalla colonna incriminata?

Semplice: un ritorno a capo non è altro che una coppia di caratteri ascii: 13 e 10.

Quindi, sulla falsa riga di questa select:

 

/* Eliminare i ritorni a capo da una colonna */
select replace(replace(myColumn, char(13), ''), char(10), '') as myColumn from myTable

 

è sufficiente impostare un'istruzione di update così da rimpiazzare questi caratteri con una stringa vuota.

Filed under:
(OT) Oggi si paga l'ici...
18 giugno 07 12.40 | abenedetti | with no comments

 

Fosse un'aziendina... ;-)

 

toobusy

Filed under:
SQL 2005 - Indici mancanti
15 giugno 07 07.18 | abenedetti | with no comments

Una delle DMV che utilizzo e vedo utilizzare più spesso è la dm_db_missing_index_details:

select * from sys.dm_db_missing_index_details

Fornisce una collezione di indici mancanti elaborata dall'ottimizzatore durante le richieste ricevute.

Attenzione però che si tratta (sempre) di warning: non è detto che il suggerimento debba essere messo in pratica!
Sicuramente l'ottimizzatore ci sta dicendo che c'è lo spazio per migliorare determinate query, ma valutarne l'implementazione resta un compito del DBA.

Mai prendere tutto per oro colato... ;-)

Filed under:
La read committed come non l'avete mai vista (2)
14 giugno 07 11.47 | abenedetti | 3 comment(s)

Evidentemente ho raggiunto lo scopo della mia sessione alla SQL Conference: attirare l'attenzione su un comportamento che risulta sconosciuto ai più.

Su un mio precedente post trovate esempio e mie considerazioni.

Dopo questo la discussione si è scatenata sul newsgroup italiano di SQL Server (news://microsoft.public.it.sql).

Se volete, tramite google groups, potete leggere l'interessante scambio di post!

Consiglio, a chi vuole, di continuare la discussione sul news...

Filed under:
[SQL Conf 07] Esperienze dai servizi di supporto Microsoft
14 giugno 07 12.54 | abenedetti | with no comments

Matteo Teruzzi, Escalation Engineer presso il team Microsoft EMEA di supporto tecnico SQL Server, comincia con l'illustrazione di due whitepaper (che consiglio vivamente) legati a statistiche e ricompilazione / plan caching in SQL Server 2005:


Racconta l'esperienza di stare in "trincea", a diretto contatto con problemi reali di clienti/scenari reali.

  • migrazione
  • dimensionamento e configurazione
  • performance
  • disponibilità

Sicuramente molto interessante, anche per l'interattività con i ragazzi che praticamente potevano (quasi) accendere un incident in diretta... ;-)

Installazione Performance Dashboard
14 giugno 07 11.47 | abenedetti | with no comments

Come hanno raccontato prima Luca, poi Stefano in SQL Conference, i Performance Dashboard risultano essere un ottimo strumento per migliorare le analisi che possiamo fare sulle nostre istanze relativamente alle performance dei db.
Troviamo lo strumento in download gratuito sul sito Microsoft.

Una volta installato due sono i passi da fare per poter utilizzare i report forniti.

  1. Dal path di installazione (Es.: C:\...\Microsoft SQL Server\90\Tools\PerformanceDashboard) prendere il file "setup.sql" ed eseguirlo sulla nostra istanza
  2. Da SSMS: tasto DX su un nostro DB --> Reports --> Custom Reports ed andiamo a selezionare il report principale "performance_dashboard_main.rdl" --> Ok

A questo punto SSMS fornirà un Warning (stiamo chiedendo l'esecuzione di un custom report...), scegliamo Run e siamo a posto!

[SQL Conf 07] Performance Dashboard e Query Performance
14 giugno 07 11.34 | abenedetti | with no comments

La terza ed ultima giornata (con una sola track) si apre con Stefano Stefani (io e gli altri MVP avevamo avuto il piacere di conoscerlo durante l'ultimo summit a Seattle), ravvenate che lavora a Redmond (da 7 anni) all'interno del team di sviluppo di SQL Server (area optimizer - come dire: vive di pane e C++).
Stefano, dalla sua esperienza e conoscenza, dispensa a piene mani nozioni, informazioni, tecniche che, da sole, valgono il prezzo dell'intera conferenza.

Performance Dashboard
- collezione di report custom per SSMS sviluppato da un guru del team di supporto SQL a Redmond
- per facilitare l'identificazione di colli di bottiglia
- i report si basano su DMV del db engine

Mostrano la CPU sia in termini di sistema che in termini di SQL Server.
L'idea di base: il motore di relazionale è un processo multithread di windows.
Quindi ad ogni istante ogni thread che compone questo processo consuma risorse o si trova in attesa.
Questi report eseguono valutazioni su entrambe le tipologie.

Di fatto non ci viene detto nulla che non avremmo potuto sapere da soli.
E' evidente che questa collezione di report ci fornisce queste info in maniera immediata, fornendoci un percorso facilitato.

Metodologia interna alla dashboard
L'analisi delle performance viene vista come un albero, un grafo, di cui ogni report rappresenta un nodo.
Si inizia analizzando dati di alto livello semplici da reperire (CPU e Waits) e, a seconda dei valori recuperati, possiamo scegliere il ramo seguente di analisi.
Man mano che il dettaglio aumenta, aumenta anche la complessità delle informazioni recuperata.
(overhead pesanti, query sempre più complicate, la dashboard può diventare sempre più intrusiva)

E' possibile scaricare gratuitamente dal download center (è necessario il SP2 sia sul server, sia sul client).

La sessione continua con una serie di demo, di codice, di analisi di piani di esecuzione fatte con una semplicità ed una preparazione e precisione disarmante.
Un'occasione incredibile di formazione per tutti!

Stefano chiude così: sappiate che, basati sui dati del supporto clienti di SQL Server, almeno il 10% delle chiamate dipendono da missing index.

[SQL Conf 07] Sessioni Day 2
13 giugno 07 10.37 | abenedetti | with no comments

Mi scuso... avrei voluto continuare raccontando live anche le sessioni della seconda giornata ma discussioni e chiacchere sulla mia sessione con gli altri speaker / amici / colleghi mi hanno tenuto un pò fuori dalla sala.

Comunque, come aveva fatto anche ieri, ci ha pensato il makka:

Se altri hanno seguito e postato impressioni e note delle sessioni BI li linkerei volentieri...

[SQL Conf 07] Livelli d'isolamento
13 giugno 07 05.39 | abenedetti | 10 comment(s)

Salgo sul palco per la prima sessione del pomeriggio: Livelli d'isolamento: guida all'uso corretto.

L'argomento non è dei più attraenti (a me, invece, piace moltissimo), in più come prima sessione dopo il pranzo rischiavo di far addormentare i ragazzi partecipanti.

 

Per questo motivo la sessione è iniziata con una demo dal titolo alquanto devastante: "La read committed come non l'avete mai vista".

Effettivamente scopo del codice era quello di stimolare l'attenzione su un risultato che (come si è dimostrato) era assolutamente inatteso.

 

Ve lo giro.

Costruiamo un db con una tabella [stipendi] assai banale, qualcosa come:

CREATE DATABASE STIPENDI
GO

USE STIPENDI
GO

/*
Attenzione alla costruzione della tabella:
- chiave primaria non clustered su colonna idRecord
- constraint unique su cognome, nome
- indice clustered su colonna valore
*/
Create table retribuzioni
(
idRecord smallint identity(1,1),
cognome varchar(35),
nome varchar(35),
valore decimal(10,2),

CONSTRAINT PK_retribuzioni PRIMARY KEY nonclustered (idRecord),
CONSTRAINT u_cognomeNome unique (cognome,nome)
)
GO

Create clustered index idx_valore on retribuzioni(valore)
GO

insert retribuzioni (cognomenomevalorevalues ('mauri','davide',1500)
insert retribuzioni (cognomenomevalorevalues ('benedetti','andrea',1000)

/* Vedo la tabella */
select from retribuzioni

Quello che ottengo é:

idRecord cognome         nome            valore
-------- --------------- --------------- ---------------------------------------
2        benedetti       andrea          1000.00
1        mauri           davide          1500.00

A questo punto apriamo due finestre di query per simulare due differenti utenti che andranno a lavorare sulla stessa tabella: connessione1 e connessione2.

Questa la connessione 1: 

/* ****************************
CONNESSIONE 1
**************************** */

USE Stipendi
GO

begin tran

        update 
retribuzioni 
            
set valore valore 2
            
where cognome 'mauri'
        
--> vado su CONNESSIONE 2 che lancia una "select * ..." sulla tabella
        --> quindi torno qui, eseguo la seconda update, la commit e la select sulla tabella
        
update retribuzioni 
            
set valore valore 2
            
where cognome 'benedetti'

commit tran

select 
from retribuzioni

 Questa la connessione 2:

/* ****************************
CONNESSIONE 2
**************************** */
USE Stipendi
GO

select from retribuzioni

Cosa otteniamo al termine delle istruzioni sulla finestra di connessione 2?

Questo:

idRecord cognome         nome            valore
-------- --------------- --------------- ---------------------------------------
2        benedetti       andrea          1000.00
2        benedetti       andrea          2000.00
1        mauri           davide          3000.00

 

Ovvero: DUE volte il mio record!

La domanda è: questo risultato è corretto, seppur non atteso? SI.

Perchè?

Perchè la connessione 1 applica un lock (tramite la update), all'interno di una transazione, il secondo record (secondo inteso come secondo in ordine di scrittura all'interno della data page).

La connessione 1 inizia a leggere e legge il primo record (idRecord 2 che non ha nessun lock) quindi, arrivato al secondo record, trovandolo lockato deve attendere che venga rilasciato.

A questo punto la connessione 2 esegue un update anche sul primo record (idRecord 2 che, avendo come nuovo "valore" una cifra più alta del secondo record, verrà scritto dopo idRecord 1 di " davide mauri") ed esegue un commit della transazione.

Ora, la connessione 1, non trovando più lock sul secondo record (idRecord 1), riprende a leggere ovvero:

- legge il record di davide mauri su cui è stato appena tolto il lock che bloccava la connessione di lettura

- continua la sua operazione di scan della tabella leggendo "nuovamente" il record di andrea benedetti che è ora scritto fisicamente dopo il record di davide mauri.

 

Perchè avviene?

Perchè il livello di isolamento read committed, livello di default di SQL Server, applica lock condivisi brevi, riga per riga, ovvero:

- durata: il tempo di leggere e processare la riga

- rilascio: prima di leggere la riga seguente

NON ho alcuna protezione su righe non ancora lette nè già lette.

 

Come sempre i commenti sono aperti!

Filed under:
[SQL Conf 07] Replica merge su media / larga scala in SQL 2005
12 giugno 07 06.23 | abenedetti | 1 comment(s)

Ultima sessione del primo giorno di conferenza.
Rob al microfono e merge replication a piene mani...

 

Merge Replication:
- fa largo uso del tempdb --> occhio all'autogrowth
- dischi diversi per log e dati (questo consiglio vale sempre, no? :-))
- separare i campi blob dalle tabelle base

 

Trigger
- vegono creati trigger ed indici sulle tabelle
- OLTP rallentato
- se utilizziamo BULK INSERT i trigger vengono "spenti" (occhio!)

 

Distributor
- tipicamente su macchina diversa
- è fondamentale per la replica transazionale (no per merge o snapshot)
- serve solo per agent history, error reporting, monitoring

 

Large Object
- utilizziamo (n)varchar(max) e NON text, ntext, image
- @stream_blob_columns = true (opzione configurabile solo a mano, no via wizard) --> altrimenti il campo viene caricato per intero in memoria

 

Altri tipi di campo
- se le tabelle NON hanno uno uniqueidentifier viene aggiunta una nuova colonna (occhio a select * from ... --> NON farlo mai ;-))
- per colonne timestamp il valore non viene replicato

 

Download-only table
- il client non può fare modifiche (con SQL CE le modifiche possono essere fatte ma non vengono replicate)
- download è incrementale (ottimizzazione - meno controlli da fare)

 

Processing Order
- fase di download: scendo prima i padri e poi i figli
- fase di upload: salgono prima i padri e poi i figli
(DRI = Declarative Referential Integritiy)
- nessun problema dal punto di vista funzionale se non esistono regole referenziali (retry automatico)

 

Snapshot
Alla prima connessione devono essere inviati sia gli schema (gli oggetti), sia i dati.
In caso di db di notevoli dimensioni o in presenza di reti / connessioni lente potrebbe essere un problema.
Fare un CD?

 

Filtri
Ovvero: dai dati che ho centralmente non posso pensare di passarli tutti ai client
- column filter: eliminare tutte le colonne che non mi servono (quali campi pubblicare)
- static row filter: identificare subset di righe in base a valori fissi (ad esempio: ordini che sono stati chiusi, clienti marcati come cancellati, ...)
- parametrized row filter: filtri con parametri (io ho il mio listino prezzi, tu il tuo) --> consentono di creare partizioni dei dati
- join filter: estendo i filtri tramite relazioni tra tabelle - utilizzare sempre gli indici!

 

Retention period
- la merge ha un periodo di "subscription expiration" o di "never expired" (occhio che con questa opzione tutti i dati della storia vengono mantenuti!)
- il tempo di "interval" dell'opzione "subscription expiration" NON è il tempo di scheduling dello snapshot (di default sono entrambi a 14 giorni) è semplicemente il tempo in cui vegono eliminate le subscription
- la retention ha in realtà un periodo (24 ore) per gestire le time-zone da aggiungere al valore di "interval" (quindi, di default, 14 gg + 24 ore)
- best pratice: usare il tempo più basso possibile

 

Consigli:
- limitare il numero di colonne
- limitare il numero di righe
- filtri parametrici (e NON più pubblicazioni con filtri statici)

 

La replica merge (Marcello, il nostro MVP mago della replica, docet) è uno strumento bellissimo.
Sicuramente fare sempre "next", "next", "next" sul wizard ci porta ad avere uno scenario funzionanente che però (probabilmente) non va bene quando le cose si complicano un pochino (e la realtà è sempre complicata ;-))

Filed under:
[SQL Conf 07] SQLCLR
12 giugno 07 04.51 | abenedetti | with no comments

Il pomeriggio continua con l'amico Paolo.
Anche lui un ottimo animale da palco (non se ne abbia a male se lo chiamo "da palco" :-))... oltre ad essere un gran professionista.

Recap
Il CLR offre vari servizi alle applicazioni (specifiche del clr o mediate dal clr)
SQL Server 2005 supporta l'aggancio (hosting) al suo interno di codice .Net
Ci sono però una serie di requisiti al contorno (già realizzati da Microsoft con la versione 2.0 del framework .Net):
- threading
- sincronizzazione
- locking
- allocazione memoria

Questo perchè qualsiasi cosa succeda il motore di SQL Server non deve mai venire meno ;-)

 

Cosa posso scrivere?
SP, UF, trigger, UDT, aggregate, ...

Il codice .Net che andremo a scrivere produce degli assembly di tipo DLL che verranno caricati all'interno del database utente che dovrà contenere gli oggetti definiti.

 

Debugging
- Le operazioni di debug richiedono una connessione ad hoc (in Windows Authentication --> si basa su DCOM)
- Bisogna essere SysAdmin
- Attenzione ai 64bit vs. 32 bit

 

Transazioni
Dove gestiamo le nostre transazioni in un ambiente distribuito?
All'interno del db, all'interno dello strato di business, all'interno dello strato di acceso ai dati, ...?
Andrebbero gestite all'interno della business logic della nostra applicazione. [vedi l'oggetto transactionScope]

Facendo in questo modo coinvolgiamo in maniera trasparente il nostro eventuale codice managed all'interno del db.
Quindi: potremmo non mettere delle "begin transaction" all'interno del nostro codice SQLCLR

 

Assembly differenti
Posso referenziare miei assembly da altri assembly?
Si, ma devo "definirlo" ad hoc "per SQL Server".
Ovvero:
- safe (default)
- external_access (usano il SQL Server Service Account!)
- unsafe (bisogna essere sysadmin)

Non posso, all'interno del mio assembly, fare delle operazioni che potrebbero portare dell'insicurezza al nostro db engine.
Ad esempio marcare con un attributo legato alla gestione del threading (se ne deve occupare SQL Server).
Inoltre ricordiamo che gli assembly "non si fidano gli uni degli altri", ovvero si vedono tra loro come partially trusted (come fosse letto da un disco di rete o da un URL)

 

WCF
Si comincia a chiedere di poter utilizzare servizi WCF.
Ad oggi NON è supportato, per cui se utilizziamo .Net 3.0 e dobbiamo consumare un servizio WCF da SQL Server 2005 possiamo consumarlo tramite il client ASP.Net e quindi dobbiamo rinunciare a tutta una serie di funzionalità legata alle sicurezze, ...

 

UDT
NON dobbiamo ragionare come tipi custom = rappresentazione dei miei oggetti (fatture, anagrafica, ...)
Possibili idee: coordinate, date e ore particolari (es.: internet time), misure, ...
Se posso rappresentare le mie entità come righe / colonne NON ha senso creare un oggetto ad hoc!

Massima attenzione sulle performance in quanto utilizzando questo tipo di dati andiamo ad introdurre un problema di scalabilità.

 

Altro post, altra domanda, per così dire a scopo di sondaggio: tra chi legge il blog ci sono dba/dev che utilizzano SQLCLR in ambienti di produzione o l'hanno fatto in sviluppo e poi hanno cambiato strada prima del rilascio?

Filed under:
[SQL Conf 07] Database mirroring
12 giugno 07 03.02 | abenedetti | 2 comment(s)

Terminata la pausa pranzo si riprende...
Ancora Luca (che, meno male, non è soporifero :-)) con il db mirroring ed esperienze fatte sul campo

Qualche punto sparso...

Cosa ci viene offerto:
- business continuity
- costi contenuti (no hw specifico, nè licenze)

 

Recap delle modalità operative:
- high performance (qualcosa potrei perdere - solo enterprise)
- high protection (failover manuale - no witness)
- high availability (failover automatico)

 

Transaction log queue
Abbiamo alcuni contatori di performance monitor per le nostre performance:
- Log Send Queue
- Redo Queue

Ricordiamo che il SP1 di SQL Server 2005 aggiunge il "Database Mirroring Monitor" che è in grado di mostrarci tutte le info relative alle code (cosa devo ancora inviare, ...).

 

Parlando di carico di lavoro...
Da misurazioni in differenti scenari applicativi vengono fuori alcuni dati interessanti.

(1) Il "data disk write rate (kb/sec)" su una macchina mirror è molto più alto rispetto alla macchina principal.
Questa elevata differenza è dovuta esclusivamente all'attività di redo log del transaction log.

Perchè?
Perchè di solito, ovvero in un database "normale", che lavora NON in uno scenario di mirroring, l'attività di scrittura sul transaction log è sempre sincrona, mentre la scrittura sul disco dati è asincrona (checkpoint).
In uno scenario di mirroring invece anche la scrittura sul disco è semre sincrona (la scelta è dettata dal poter fornire il minor tempo possibile di indisponibilità dei dati nel caso in cui il mirror dovesse essere messo disponibile).

(2) La creazione degli indici clustered, con SAFETY = FULL, è molto superiore su una macchina mirror (hanno un log generation rate molto più elevato)
Potrei:
- impostare il safety level a OFF solo per il tempo necessario (posso modificarlo al volo)
- mettere in pausa il mirroring (SUSPEND) --> attenzione ai tempi di riallineamento delle code

 

DB Mirroring su reti geografiche
1) banda adeguata
2) minima latenza di rete (può fare la differenza!)
3) se il Principal resta isolato (non sente mirror o witness) si "autosospende"
4) encryption sul traffico di rete (endpoint, impostazione predefinita)

 

Applicazioni Legacy
Per avere failover automatico occorrono le librerie ADO.Net 2.0 o SNAC (SQL Native Access Client)
[Vedi la proprietà failover partner sulla stringa di connessione]
Le altre applicazioni posso sfruttare gli alias del DNS per essere reindirizzati in maniera quasi automatica (tempi di replica tra i DNS?)

 

Snapshot
Se lo uso serve una licenza
E' l'unico modo di utilizzare un db mirror (sola lettura ;-))
Da valutare se conviene creare uno snapshot direttamente sul principal (ha il disco meno stressato)

Filed under:
[OT] Linea ADSL - (sembra) finita
12 giugno 07 12.37 | abenedetti | with no comments

<polemica>
A quanto pare oggi è proprio una bella giornata!
Ricevo una telefonata da mia moglie, a casa con il piccolo Simone, che mi dice, più o meno testualmente: habemus ADSL!

In data 12.01, 5 mesi fa (!!!), ho fatto richiesto di una linea dati.
Bene: sono nella regione più ricca d'italia, sono nella terra della Leonessa (Brescia), sono in una delle provincie più produttive del paese dove il principale verbo utilizzato è "produrre" e... per avere una maledetta linea bisogna aspettare 5 mesi.

Auguri alla competitività. Viva il sistema.
</polemica>

Scusate il post ;-)

Filed under:
[SQL Conf 07] SP2: non solo fix
12 giugno 07 12.27 | abenedetti | with no comments

Luca tiene una delle due seconde sessioni della mattina.
Con la solita preparazione e la solita chiarezza.

Alcuni punti, come prima, in ordine sparso:

varDecimal
- ricordiamoci sempre che non si tratta di un datatype ma di un formato di memorizzazione (solo Enterprise e Developer edition. Attenzione: non posso fare un attach di un db con varDecimal su una versione che non supporti la feature)

Alter login & Alter user
- alter login with password hashed mancava questa possibilità in scenari come log shipping, mirroring, ...
- alter user with login come alternativa di sp_change_users_login (attenzione che non è ancora documentata nemmeno sui BOL di maggio 2007)

Piani di manutenzione
- posso utilizzarli direttamente dal db engine (non sono più necessari SSIS o client tools)
- cleanup task su base oraria :-(

Custom report in management studio
- posso fare report custom
- NON servono i reporting services

Common criteria compliance
- è una certificazione riconosciuta da 24 paesi del mondo (ISO 15408) per sistemi informatici
- SQL Server 2005 SP1 è al più alto livello di certificazione (EAL1)
- SQL Server 2005 SP2 è in corso di valutazione EAL4+
- funzionalità disponibile solo in versioni di fascia alta (Enterprise e Developer)
- rende possibile:
  - residual information protection
  - visualizza info aggiuntive in sys.dm_exec_sessions ((last) successfull / unsuccessfull logon)

Un consiglio che vale sempre: assicuriamoci di avere sempre una certa omogeneità di (SQL) Server (come edizioni e sp / fix) in azienda o dal nostro cliente ;-)

Chiudo con una domanda: qualcuno utilizza già alcune di queste funzionalità?

Filed under:
More Posts Next page »

This Blog

Syndication