Business Geek

Aller au contenu | Aller au menu | Aller à la recherche

mardi 12 août 2008

Indexation - Faites la chasse aux index HEAP

Un premier post qui j'espère me conduira à une série sur l'indexation dans SQL Server. Je traiterai les points un peu dans le désordre mais n'est-ce pas là l'attrait d'un blog ? Je sais que je ne commence pas par les bases mais bon, j'attend vos questions :-).

Un index de type HEAP indique en réalité le fait qu'il n'y ait aucun index sur la table et surtout pas d'index CLUSTERED. C'est à dire que seul le CREATE TABLE a été exécuté, sans aucune option, sans PRIMARY KEY.

Cela signifie que les données sont rangées n'importe comment ou plutôt dans l'ordre de leur création. C'est comme si je prenais un annuaire et que je mélangais les villes et les noms.

La conséquence d'avoir ce type d'indexation dans sa base de données est très souvent d'avoir des performances catastrophiques lors de la selection de données. D'autant plus quand la volumétrie augmente. Ceci vient du fait que l'opération qui est faite sur la table pour récupérer un jeu d'enregistrement est un TABLE SCAN (aussi appelé Full Scan).

Pour en revenir à mon annuaire, c'est comme si je vous demandais de me trouver toutes les personnes qui habitent au 12, rue des saules, quelque soit la ville. Vous seriez obligé de lire (scanner) toutes les pages.

Pour limiter cela, on peut mettre un index clustered ou une PRIMARY KEY (équivalent d'un index unique non null) pour optimiser la recherche.

Pour retrouver toutes les tables concernées :

select OBJECT_NAME(sys.indexes.object_id)
from sys.indexes
  inner join sys.tables on sys.tables.object_id = sys.indexes.object_id
where sys.indexes.[type] = 0 --0 = HEAP

Donc faite un petit check-up de vos bases et vérifier vos tables stockées sur un index HEAP... Et pourquoi pas les mettre sur un index CLUSTERED... mais je reviendrai sur ce point ;-)

 

 

 

 

 

jeudi 7 août 2008

SQL Server 2008 est RTM...

...depuis quelques heures déjà.


Désolé de ne pas plus m'étendre plus sur cette nouvelle mais je suis chez un client en plein audit de perfs alors je développerai ce soir, pendant l'installation ;-)

dimanche 3 août 2008

Récupérer la taille d'une base de données

ll existe différentes techniques pour récupérer la taille d'une base de données. Je vous en livre ici une que j'utilise. Elle se base sur la vue système sys.database_files qui nous renseigne sur les fichiers de la base de données.

SELECT dbname, [ROWS]*8 as Donnees, [LOG]*8 as Journaux
FROM
   (SELECT DB_NAME() as dbname, type_desc, size
   FROM sys.database_files) as p
PIVOT
   (SUM(size) FOR type_desc IN ([ROWS], [LOG])) as pvt

Grâce à la fonction PIVOT, j'aggrège les fichiers de données et journaux. Vous noterez aussi que je multiplie la taille par 8 car la valeur de cette vue correspond à un nombre de pages (8KB). Nous obtenons donc une taille en kilo-octets.

Pour connaître les tailles de toutes les bases de données d'un serveur, on peut utiliser se script combiné avec la fonction système sp_MSforeachDB

CREATE TABLE #TMP_DB_Sizes (
  dbname sysname,
  datasizeinkb int,
  logsizeinkb int)

EXECUTE sp_msforeachdb '
INSERT INTO #TMP_DB_Sizes
SELECT dbname, [ROWS]*8 as Donnees, [LOG]*8 as Journaux
FROM
   (SELECT ''[?]'' as dbname, type_desc, size
   FROM [?].sys.database_files) as p
PIVOT
   (SUM(size) FOR type_desc IN ([ROWS], [LOG])) as pvt'

select * from #TMP_DB_Sizes

drop table #TMP_DB_Sizes

J'utilise une table temporaire pour n'avoir qu'un jeu de résultat. Vous noterez l'utilisation de '[?]' pour injecter le nom de la base en cours dans le script

Il existe bien évidemment d'autres solutions, venant de 2000 ou de 2005, certaines apportant d'autres informations comme le pourcentage d'espace inutilisé.

Bon audit !!

Transactions imbriquées et SAVE TRANSACTION

Lorsque l'on travaille avec des transactions imbriquées, on veut parfois pour voir annuler une transaction intermédiaire mais garder les précédentes opérations.

En T-SQL, l'opération de ROLLBACK annule l'ensemble des niveaux de transactions (scopes). Pour s'en convaincre, cette citation de la documentation (ROLLBACK) :

When nesting transactions, this same statement rolls back all inner transactions to the outermost BEGIN TRANSACTION statement.

Le code suivant montre un exemple du problème. Le premier ROLLBACK annule tout depuis la transaction A. La variable @@trancount permet de voir qu'il n'y a plus de transaction en cours

BEGIN TRAN A
-------on démarre le premier niveau de transaction

INSERT INTO [AdventureWorks].[dbo].[truc]([a],[b])
VALUES ('transaction A','transaction A')

select @@trancount --returns 1

BEGIN TRAN B
-------on démarre le deuxième niveau de transaction

INSERT INTO [AdventureWorks].[dbo].[truc]([a], [b])
VALUES ('transaction B','transaction B')

select @@trancount --returns 2

ROLLBACK TRANSACTION B
--on annule la transaction intermédiaire

select @@trancount
--returns 0 : plus de transaction en cours

COMMIT TRAN A --génère une erreur
--Msg 6401, Level 16, State 1, Line 19
--Cannot roll back B. No transaction or savepoint of that name was found.

Ce comportement ne nous permet donc pas d'annuler une partie du traitement tout en gardant le reste. Heureusement, l'instruction SAVE TRANSACTION nous permet de corriger le tir. SAVE TRANSACTION permet de mettre un point de sauvegarde dans la transaction en cours pour pouvoir y revenir par la suite, avec l'instruction ROLLBACK.

Voici le script modifié. A la fin, la ligne A est insérée mais pas la B.

BEGIN TRAN A
-------on démarre le premier niveau de transaction

INSERT INTO [AdventureWorks].[dbo].[truc]([a],[b])
VALUES ('transaction A','transaction A')

select @@trancount --returns 1

BEGIN TRAN B
-------on démarre le deuxième niveau de transaction

SAVE TRANSACTION B_Saved
--on met un point de sauvegarde

INSERT INTO [AdventureWorks].[dbo].[truc]([a], [b])
VALUES ('transaction B','transaction B')

select @@trancount --returns 2

ROLLBACK TRANSACTION B_Saved

COMMIT B
--on force quand même un commit pour valider la transaction B

select @@trancount --returns 1

COMMIT TRAN A

A noter que l'on doit quand même faire un COMMIT de la transaction enfant car le retour à un point de sauvegarde ne termine pas la transaction.

jeudi 26 juin 2008

Comparaison SQL Server 2008 et Oracle 11g

Un très bon article forcément partisan mais qui permet de lister les atouts de SQL Server 2008 (et pourquoi pas même 2005) par rapport à son grand rival Oracle.

Le livre blanc est accessible à cette adresse : SQL Server 2008 Compared to Oracle Database 11g

Moi j'aime bien la comparaison des prix ;-)

jeudi 12 juin 2008

De belles références

Non, ce n'est pas un jeu de mot pour présenter une nouvelle Assembly. Je parle ici de références clients qui utilisent avec succès SQL Server.
Le tout présenté dans une petite application Silverlight.

Le site est ici : http://www.microsoft.com/france/sql/ilslontfait/

Les références sont :

  • JCDecaux (plus connu sous le nom de Velib') : 400 000 locations par jour
  • Premier Bankcard : un datawarehouse de 20 To (27 milliards de lignes)
  • AFP : 4000 utilisateurs en simultanés
  • Xiti : 17 milliards d'enregistrements par mois
  • AXA : Business Intelligence temps réel
  • Nancy-Université : réduction des coûts de SAP

lundi 9 juin 2008

SQL Server 2008 Web Edition

Tellement excité à l'idée d'installer la RC0 de SQL Server 2008, j'ai écarté un détail pourtant visible dès la page de téléchargement...

Il y a une nouvelle édition de SQL Server qui complète la gamme :

SQL Server 2008 Web Edition

En discutant avec différents camarades de jeu, nous nous sommes posés cette simple question : mais qu'est ce que c'est ???

Aux premières informations, ce serait une édition spéciale pour les hébergeurs pour faire baisser les prix du hosting basé sur SQL Server. Bien qûr, je reste à l'affût dès que j'en sais plus..

 

Plus d'infos : http://mshostingsummit08.spaces.live.com/blog/cns!4308FE7290C0AF4!195.entry

Premiers pas dans l'espace

Il y a plusieurs semaines, j'ai terminé un article d'introduction aux fonctionnalités spatiales de SQL Server 2008. Voici quelques extraits pour vous mettre en appétit. Et pour aller directement sur l'article complet :

      Premiers pas dans l'espace (www.bewise.fr)

Introduction
Cet article se veut une première introduction aux nouveaux types spatiaux de SQL Server 2008. Je vais vous les présenter et nous les manipulerons. Nous aborderons aussi leur utilisation avec du code .NET. Enfin, nous utiliserons Virtual Earth pour présenter les données géographiques mais nous ne rentrerons pas dans le détail de cette technologie.

[...]

Premières requêtes
Les 2 nouveaux types proposent toute une série de méthodes pour manipuler des données spatiales. Aire de la surface, surface circonscrite, inscrite, périmètre, intersection, union, barycentre… Le but n’est pas de vous les décrire ici une à une. Nous allons toutefois en utiliser quelques unes dans des requêtes simples mais indispensables dans une application gérant des types spatiaux.

Tout d’abord, voyons comment retrouver les points contenus dans une zone donnée. Comme cas concret, on peut imaginer une recherche d’appartements ou d’hôtels dans une zone définie. Pour cela, nous avons plusieurs possibilités avec les méthodes STContains, STIntersects et STWithin. La méthode STIntersects serra utilisée pour le type geography car les 2 autres n’existent que sur le type geometry. Voici le code T-SQL permettant cette requête :

Declare @zone geography = geography::STPolyFromText('POLYGON((43 3.2, 43 3.5, 43.2 3))', 4326)

Select *
From CustomerPlaces
Where @zone.STIntersects(CustomerPlaces.Localization) = 1

[...]

ADO.NET
Après avoir vu un aperçu des types spatiaux et de leur utilisation dans SQL dans Management Studio, intéressons nous à la manipulation depuis une application .NET.

[...]

Et comme d'habitude, n'hésitez pas pour les questions...

SQL Server 2008 RC0

On y est presque... Ce n'est pas encore la RTM mais on s'en approche. La 1ère Release Candidate (RC0) de SQL Server 2008 est disponible pour les abonnés MSDN et Technet. Cette version a normalement le même périmètre que la version finale.

Il y a un seul Setup pour toutes les versions et le téléchargement se passe ici : https://msdn.microsoft.com/en-us/subscriptions/securedownloads/details/default.aspx?pm=pid%3a334%7CLk:t

Je suis en pleine installation, en mode side-by-side. Je ferai des retours réguliers sur cette version quasi-finale.

jeudi 24 avril 2008

De l'utilisation de NOLOCK

J'ai eu il y a quelques temps la question suivante :

j'aimerais faire comprendre à mes développeurs l'intéret de positionner des NOLOCK dans les requêtes de sélection, peux-tu m'aider pour faire l'argumentaire

Pour rappel ou pour ceux qui ne voient pas de quoi je parle, NOLOCK est un Query Hint qui permet de passer le mode d'isolation au niveau le plus bas sur la lecture d'une table. Il s'utilise de la façon suivante :

Select * From MaTable WITH (NOLOCK)

Voici la réponse que j'ai donné :

Premièrement et c'est le plus important, utiliser NOLOCK n'est pas « naturel », dans le sens où la base de donnnées est là pour garantir les accès concurrents et gérer des lecture/écriture dans une optique transactionnelle (contraintes ACID1) et ceux même pour un énorme volume de transactions.

Cependant, sans aller jusqu'à dire que c'est un constat d'échec que de l'utiliser, le hint NOLOCK est intéressant dans certains contextes.
Notamment les sites Web qui font beaucoup d'accès en lecture pour faire principalement de l'affichage. Dans ce cas, en effet, avoir une donnée non commitée n'est (en général) pas critique, sauf pour certains sites (bourses, état de stock, etc.). Cela permet de soulager la base de données et de booster l'affichage des pages.

Mais pour moi, le NOLOCK n'est qu'une réponse technique d'urgence et ne sert juste qu'à cacher la poussière sous le tapis. Il faut comprendre pourquoi l'ajout d'une ligne dans une facture bloque l'affichage du top 10 des vendeurs et essayer d'y répondre par la conception de l'application (cache, portée des transactions, etc.) ou de la base (normalisation/dénormalisation).
J'insiste qu'il y a un risque à utiliser NOLOCK à tout va, car on peut récupérer des données "dirty" et les réécrire par la suite et perdre la cohérence (aCid); à l'application d'adresser cette contrainte.

Donc pour conclure :

  • le NOLOCK est une réponse technique intéressante pour optimiser l'affichage de données NON CRITIQUES
  • l'utilisation systématique du NOLOCK n'est pas une bonne chose car elle cache un réel problème transactionnel. Et surtout on ne respecte plus la "norme" ACID.

Si tu utilises SQL Server 2005, il faut te tourner vers les autres niveaux de verrou comme le Snapshot (READ_COMMITTED_SNAPSHOT) qui apporte la souplesse en lecture tout en garantissant les transactions (comme le fait Oracle). Un bon argument pour passer à 2005.

1ACID: Atomicité, Cohérence, Isolation, Durabilité

- page 2 de 6 -