SQL conception et mise en Ĺ“uvre

Formation SQL1

Dalibo SCOP

8 janvier 2018

Licence Creative Commons CC-BY-NC-SA

Vous êtes libres de redistribuer et/ou modifier cette création selon les conditions suivantes :

  • PaternitĂ©

  • Pas d'utilisation commerciale

  • Partage des conditions initiales Ă  l'identique

Introduction et premiers SELECT

Préambule

  • Qu'est-ce que le standard SQL ?
  • Comment lire des donnĂ©es
  • Quel type de donnĂ©es est disponible ?
  • Principes d'une base de donnĂ©es
  • Premières requĂŞtes
  • ConnaĂ®tre les types de donnĂ©es

Objectifs

  • Comprendre les principes
  • Écrire quelques requĂŞtes en lecture
  • ConnaĂ®tre les diffĂ©rents types de donnĂ©es
    • et quelques fonctions très utiles

Principes d'une base de données

  • Base de donnĂ©es
    • ensemble organisĂ© d'informations
  • Système de Gestion de Bases de DonnĂ©es
    • acronyme SGBD (DBMS en anglais)
    • programme assurant la gestion et l'accès Ă  une base de donnĂ©es
    • assure la cohĂ©rence des donnĂ©es

Type de bases de données

  • Modèle hiĂ©rarchique
  • Modèle rĂ©seau
  • Modèle relationnel
  • Modèle objet
  • Modèle relationnel-objet
  • NoSQL

Type de bases de données (1)

  • Modèle hiĂ©rarchique
    • structure arborescente
    • redondance des donnĂ©es
  • Modèle rĂ©seau
    • structure arborescente, mais permettant des associations
    • ex : Bull IDS2 sur GCOS

Type de bases de données (2)

  • Modèle relationnel
    • basĂ© sur la thĂ©orie des ensembles et la logique des prĂ©dicats
    • standardisĂ© par la norme SQL
  • Modèle objet
    • structure objet
    • pas de standard
  • Modèle relationnel-objet
    • le standard SQL ajoute des concepts objets

Type de bases de données (3)

  • NoSQL : « Not only SQL »
    • pas de norme de langage de requĂŞte
    • clĂ©-valeur (Redis, Riak)
    • graphe (Neo4J)
    • document (MongoDB, CouchDB)
    • orientĂ© colonne (HBase)
  • Rapprochement relationnel/NoSQL
    • PostgreSQL permet de stocker des documents (JSON, XML)

Modèle relationnel

  • IndĂ©pendance entre la vue logique et la vue physique
    • le SGBD gère lui-mĂŞme le stockage physique
  • Table ou relation
  • Un ensemble de tables reprĂ©sente la vue logique

Caractéristiques du modèle relationnel

  • ThĂ©orie des ensembles
  • Logique des prĂ©dicats
  • Logique 3 Ă©tats

ACID

  • AtomicitĂ© (Atomic)
  • CohĂ©rence (Consistent)
  • Isolation (Isolated)
  • DurabilitĂ© (Durable)

Langage SQL

  • Norme ISO 9075
    • dernière version stable : 2016
  • Langage dĂ©claratif
    • on dĂ©crit le rĂ©sultat et pas la façon de l'obtenir
    • comme Prolog
  • Traitement ensembliste
    • par opposition au traitement procĂ©dural
    • « on effectue des opĂ©rations sur des relations pour obtenir des relations »

SQL est un langage

  • Langage
    • règles d'Ă©criture
    • règles de formatage
    • commentaires
  • AmĂ©liore la lisibilitĂ© d'une requĂŞte

Recommandations d'Ă©criture et de formatage

  • Écriture
    • mots clĂ©s SQL en MAJUSCULES
    • identifiants de colonnes/tables en minuscule
  • Formatage
    • dissocier les Ă©lĂ©ments d'une requĂŞte
    • un prĂ©dicat par ligne
    • indentation

Commentaires

  • Commentaire sur le reste de la ligne

    -- commentaire
  • Commentaire dans un bloc

    /* bloc
     */

Les 4 types d'ordres SQL

  • DDL
    • Data Definition Language
    • dĂ©finit les structures de donnĂ©es
  • DML
    • Data Manipulation Language
    • manipule les donnĂ©es
  • DCL
    • Data Control Language
    • contrĂ´le l'accès aux donnĂ©es
  • TCL
    • Transaction Control Language
    • contrĂ´le les transactions

Lecture de données

  • Ordre SELECT
    • lecture d'une ou plusieurs tables
    • ou appel de fonctions

Syntaxe de SELECT

SELECT expressions_colonnes
 [ FROM elements_from ]
 [ WHERE predicats ]
 [ ORDER BY expressions_orderby ]
 [ LIMIT limite ]
 [ OFFSET offset ];

Liste de sélection

  • Description du rĂ©sultat de la requĂŞte
    • colonnes retournĂ©es
    • renommage
    • dĂ©doublonnage

Colonnes retournées

  • Liste des colonnes retournĂ©es
    • expression
    • sĂ©parĂ©es par une virgule
  • Expression
    • constante
    • rĂ©fĂ©rence de colonne :

      table.colonne
  • opĂ©ration sur des colonnes et/ou des constantes

Alias de colonne

  • Renommage
    • ou alias
    • AS :

      expression AS alias
  • le rĂ©sultat portera le nom de l'alias

Dédoublonnage des résultats

  • DĂ©doublonnage des rĂ©sultats avant de les retourner
    • DISTINCT
    • Ă  ne pas utiliser systĂ©matiquement
  • SELECT DISTINCT expressions_colonnes...

DĂ©rivation

  • SQL permet de dĂ©river les valeurs des colonnes
    • opĂ©rations arithmĂ©tiques : +, -, /, *
    • concatĂ©nation de chaĂ®nes : ||
    • appel de fonction

Fonctions utiles

  • Fonctions sur donnĂ©es temporelles :
    • date et heure courante : now()
    • âge : age(timestamp)
    • extraire une partie d'une date : extract( 'year' FROM timestamp)
    • ou date_part('Y',timestamp)
  • Fonctions sur donnĂ©es caractères :
    • longueur d'une chaĂ®ne de caractère : char_length(chaine)
  • Compter les lignes : count(*)

Clause FROM

FROM expression_table [, expression_table ...]
  • Description des tables mises en Ĺ“uvre dans la requĂŞte
    • une seule table
    • plusieurs tables jointes
    • sous-requĂŞte

Alias de table

  • mot-clĂ© AS
    • optionnel :

      reference_table alias
  • la table sera ensuite rĂ©fĂ©rencĂ©e par l'alias

    reference_table [AS] alias
    reference_table AS alias (alias_colonne1, ...)

Nommage des objets

  • Noms d'objets convertis en minuscules
    • Nom_Objet devient nom_objet
    • certains nĂ©cessitent l'emploi de majuscules
  • Le guillemet double " conserve la casse
    • "Nom_Objet"

Clause WHERE

  • Permet d'exprimer des conditions de filtrage
    • prĂ©dicats
  • Un prĂ©dicat est une opĂ©ration logique
    • renvoie vrai ou faux
  • La ligne est prĂ©sente dans le rĂ©sultat
    • si l'expression logique des prĂ©dicats est vraie

Expression et opérateurs de prédicats

  • Comparaison
    • =, <, >, =<, >=, <>
  • NĂ©gation
    • NOT
expression operateur_comparaison expression

Combiner des prédicats

  • OU logique
    • predicat OR predicat
  • ET logique
    • predicat AND predicat

Correspondance de motif

  • Comparaison de motif

    chaine LIKE motif ESCAPE 'c'
  • % : toute chaine de 0 Ă  plusieurs caractères
    • _ : un seul caractère
  • Expression rĂ©gulière POSIX

    chaine ~ motif

Listes et intervalles

  • Liste de valeurs

    expression IN (valeur1 [, ...])
  • Chevauchement d'intervalle de valeurs

    expression BETWEEN expression AND expression
  • Chevauchement d'intervalle de dates

    (date1, date2) OVERLAPS (date3, date4)

Tris

  • SQL ne garantit pas l'ordre des rĂ©sultats
    • tri explicite requis
  • Tris des lignes selon des expressions

    ORDER BY expression  [ ASC | DESC | USING opérateur ]
                         [ NULLS { FIRST | LAST } ] [, ...]
  • ordre du tri : ASC ou DESC
    • placement des valeurs NULL : NULLS FIRST ou NULLS LAST
    • ordre de tri des caractères : COLLATE collation

Limiter le résultat

  • Obtenir des rĂ©sultats Ă  partir de la ligne n
    • OFFSET n
  • Limiter le nombre de lignes Ă  n lignes
    • FETCH {FIRST | NEXT} n ROWS ONLY
    • LIMIT n
  • OpĂ©rations combinables
    • OFFSET doit apparaitre avant FETCH
  • Peu d'intĂ©rĂŞt sur des rĂ©sultats non triĂ©s

Utiliser plusieurs tables

  • Clause FROM
    • liste de tables sĂ©parĂ©es par ,
  • Une table est combinĂ©e avec une autre
    • jointure
    • produit cartĂ©sien

Types de données

  • Type de donnĂ©es
    • du standard SQL
    • certains spĂ©cifiques PostgreSQL

Qu'est-ce qu'un type de données ?

  • Le système de typage valide les donnĂ©es
  • Un type dĂ©termine
    • les valeurs possibles
    • comment les donnĂ©es sont stockĂ©es
    • les opĂ©rations que l'on peut appliquer

Types de données

  • Types standards SQL
  • Types dĂ©rivĂ©s
  • Types spĂ©cifiques Ă  PostgreSQL
  • Types utilisateurs

Types standards (1)

  • Caractère
    • char, varchar
  • NumĂ©rique
    • integer, smallint, bigint
    • real, double precision
    • numeric, decimal
  • BoolĂ©en
    • boolean

Types standards (2)

  • Temporel
    • date, time
    • timestamp
    • interval
  • ChaĂ®nes de bit
    • bit, bit varying
  • Formats validĂ©s
    • XML

Caractères

  • char(n)
    • longueur fixe
    • de n caractères
    • complĂ©tĂ© Ă  droite par des espaces si nĂ©cessaire
  • varchar(n)
    • longueur variable
    • maximum n caractères
    • n optionnel

Représentation données caractères

  • Norme SQL
    • chaĂ®ne encadrĂ©e par '
    • 'chaĂ®ne de caractères'
  • ChaĂ®nes avec Ă©chappement du style C
    • chaĂ®ne prĂ©cĂ©dĂ©e par E ou e
    • E'chaĂ®ne de caractères'
  • ChaĂ®nes avec Ă©chappement Unicode
    • chaĂ®ne prĂ©cĂ©dĂ©e par U&
    • U&'chaĂ®ne de caractères'

Numériques

  • Entier
    • smallint, integer, bigint
    • signĂ©s
  • Virgule flottante
    • real, double precision
    • valeurs inexactes
  • PrĂ©cision arbitraire
    • numeric(precision, echelle), decimal(precision, echelle)
    • valeurs exactes

Représentation de données numériques

  • Chiffres dĂ©cimaux : 0 Ă  9
  • SĂ©parateur dĂ©cimal : .
  • chiffres
  • chiffres.[chiffres][e[+-]chiffres]
  • [chiffres].chiffres[e[+-]chiffres]
  • chiffrese[+-]chiffres
  • Conversion
    • TYPE 'chaine'

Booléens

  • boolean
  • 3 valeurs possibles
    • TRUE
    • FALSE
    • NULL (ie valeur absente)

Temporel

  • Date
    • date
  • Heure
    • time
    • avec ou sans fuseau horaire
  • Date et heure
    • timestamp
    • avec ou sans fuseau horaire
  • Intervalle de temps
    • interval

Représentation des données temporelles

  • Conversion explicite
    • TYPE 'chaine'
  • Format d'un timestamp
    • 'YYYY-MM-DD HH24:MI:SS.ssssss'
    • 'YYYY-MM-DD HH24:MI:SS.ssssss+fuseau'
    • 'YYYY-MM-DD HH24:MI:SS.ssssss' AT TIME ZONE 'fuseau'
  • Format d'un intervalle
    • INTERVAL 'durĂ©e interval'

Gestion des fuseaux horaires

  • Paramètre timezone
  • Session : SET TIME ZONE
  • Expression d'un fuseau horaire
    • nom complet : 'Europe/Paris'
    • nom abbrĂ©gĂ© : 'CEST'
    • dĂ©calage : '+02'

Chaînes de bits

  • ChaĂ®nes de bits
    • bit(n), bit varying(n)

Représentation des chaînes de bits

  • ReprĂ©sentation binaire
    • ChaĂ®ne de caractères prĂ©cĂ©dĂ©e de la lettre B
    • B'01010101'
  • ReprĂ©sentation hexadĂ©cimale
    • ChaĂ®ne de caractères prĂ©cĂ©dĂ©e de la lettre X
    • X'55'

XML

  • Type validĂ©
    • xml
  • ChaĂ®ne de caractères
    • validation du document XML

Types dérivés

  • Types spĂ©cifiques Ă  PostgreSQL
  • SĂ©riĂ©s
    • principe de l'« autoincrement »
    • serial
    • smallserial
    • bigserial
    • Ă©quivalent Ă  un type entier associĂ© Ă  une sĂ©quence et avec une valeur par dĂ©faut
    • (v 10+) prĂ©fĂ©rer un type entier + la propriĂ©tĂ© IDENTITY
  • Caractères
    • text

Types additionnels non SQL

  • bytea
  • array
  • enum
  • cidr, inet, macaddr
  • uuid
  • json
  • jsonb
  • hstore
  • range

Types utilisateurs

  • Types utilisateurs
    • composites
    • Ă©numĂ©rĂ©s (enum)
    • intervalles (range)
    • scalaires
    • tableau

      CREATE TYPE

Conclusion

  • SQL : traitement d'ensembles d'enregistrements
  • Pour les lectures : SELECT
  • Nom des objets en minuscules
  • Des types de donnĂ©es simples et d'autres plus complexes

Bibliographie

  • Bases de donnĂ©es - de la modĂ©lisation au SQL (Laurent Audibert)
  • SQL avancĂ© : programmation et techniques avancĂ©es (Joe Celko)
  • SQL : Au coeur des performances (Markus Winand)
  • The Manga Guide to Databases (Takahashi, Mana, Azuma, Shoko)
  • The Art of SQL (StĂ©phane Faroult)

Questions

N'hésitez pas, c'est le moment !

Travaux Pratiques

Création d'objet et mises à jour

Introduction

  • DDL, gĂ©rer les objets
  • DML, Ă©crire des donnĂ©es
  • GĂ©rer les transactions
  • DDL (Data Definition Language)
  • DML (Data Manipulation Language)
  • TCL (Transaction Control Language)

Objectifs

  • Savoir crĂ©er, modifier et supprimer des objets
  • Savoir utiliser les contraintes d'intĂ©gritĂ©
  • Savoir mettre Ă  jour les donnĂ©es
  • Savoir utiliser les transactions

DDL

  • DDL
    • Data Definition Language
    • langage de dĂ©finition de donnĂ©es
  • Permet de crĂ©er des objets dans la base de donnĂ©es

Objets d'une base de données

  • Objets dĂ©finis par la norme SQL :
    • schĂ©mas
    • sĂ©quences
    • tables
    • contraintes
    • domaines
    • vues
    • fonctions
    • triggers

Créer des objets

  • Ordre CREATE
  • Syntaxe spĂ©cifique au type d'objet
  • Exemple :
CREATE SCHEMA s1;

Modifier des objets

  • Ordre ALTER
  • Syntaxe spĂ©cifique pour modifier la dĂ©finition d'un objet, exemple:
  • renommage

    ALTER type_objet ancien_nom RENAME TO nouveau_nom ;
  • changement de propriĂ©taire

    ALTER type_objet nom_objet OWNER TO proprietaire ;
  • changement de schĂ©ma

    ALTER type_objet nom_objet SET SCHEMA nom_schema ;

Supprimer des objets

  • Ordre DROP
  • Exemples :
    • supprimer un objet :

      DROP type_objet nom_objet ;
  • supprimer un objet et ses dĂ©pendances :

    DROP type_objet nom_objet CASCADE ;

Schéma

  • Identique Ă  un espace de nommage
  • Permet d'organiser les tables de façon logique
  • PossibilitĂ© d'avoir des objets de mĂŞme nom dans des schĂ©mas diffĂ©rents
  • Pas d'imbrication (contrairement Ă  des rĂ©pertoires par exemple)
  • SchĂ©ma public
    • crĂ©Ă© par dĂ©faut dans une base de donnĂ©es PostgreSQL

Gestion d'un schéma

  • CREATE SCHEMA nom_schĂ©ma
  • ALTER SCHEMA nom_schĂ©ma
    • renommage
    • changement de propriĂ©taire
  • DROP SCHEMA [ IF EXISTS ] nom_schĂ©ma [ CASCADE ]

Accès aux objets

  • Nommage explicite
    • nom_schema.nom_objet
  • Chemin de recherche de schĂ©ma
    • paramètre search_path
    • SET search_path = schema1,schema2,public;
    • par dĂ©faut : $user, public

SĂ©quences

  • SĂ©quence
    • gĂ©nère une sĂ©quence de nombres
  • Paramètres
    • valeur minimale MINVALUE
    • valeur maximale MAXVALUE
    • valeur de dĂ©part START
    • incrĂ©ment INCREMENT
    • cache CACHE
    • cycle autorisĂ© CYCLE

Création d'une séquence

CREATE SEQUENCE nom [ INCREMENT incrément ]
    [ MINVALUE valeurmin | NO MINVALUE ]
    [ MAXVALUE valeurmax | NO MAXVALUE ]
    [ START [ WITH ] début ]
    [ CACHE cache ]
    [ [ NO ] CYCLE ]
    [ OWNED BY { nom_table.nom_colonne | NONE } ]

Modification d'une séquence

ALTER SEQUENCE nom [ INCREMENT increment ]
    [ MINVALUE valeurmin | NO MINVALUE ]
    [ MAXVALUE valeurmax | NO MAXVALUE ]
    [ START [ WITH ] début ]
    [ RESTART [ [ WITH ] nouveau_début ] ]
    [ CACHE cache ] [ [ NO ] CYCLE ]
    [ OWNED BY { nom_table.nom_colonne | NONE } ]
  • Il est aussi possible de modifier
    • le propriĂ©taire
    • le schĂ©ma

Suppression d'une séquence

DROP SEQUENCE nom [, ...]

SĂ©quences, utilisation

  • Obtenir la valeur suivante
    • nextval('nom_sequence')
  • Obtenir la valeur courante
    • currval('nom_sequence')
    • mais nextval() doit ĂŞtre appelĂ© avant dans la mĂŞme session

Type SERIAL

  • Type serial/bigserial/smallserial
    • sĂ©quence gĂ©nĂ©rĂ©e automatiquement
    • valeur par dĂ©faut nextval(...)
  • (v 10+) PrĂ©fĂ©rer un entier avec IDENTITY

Domaines

  • Permet d'associer
    • un type standard
    • et une contrainte (optionnelle)
Un domaine est utilisé pour définir un type utilisateur qui est en fait un

Tables

  • Équivalent ensembliste d'une relation
  • ComposĂ© principalement de
    • colonnes ordonnĂ©es
    • contraintes

Création d'une table

  • DĂ©finition de son nom
  • DĂ©finition de ses colonnes
    • nom, type, contraintes Ă©ventuelles
  • Clauses de stockage
  • CREATE TABLE

CREATE TABLE

CREATE TABLE nom_table (
  definition_colonnes
  definition_contraintes
) clause_stockage;

DĂ©finition des colonnes

nom_colonne type [ COLLATE collation ] [ contrainte ]
[, ...]

Valeur par défaut

  • DEFAULT
    • affectation implicite
  • Utiliser directement par les types sĂ©riĂ©s

Copie de la définition d'une table

  • CrĂ©ation d'une table Ă  partir d'une autre table
    • CREATE TABLE ... (LIKE table clause_inclusion)
  • Avec les valeurs par dĂ©faut des colonnes :
    • INCLUDING DEFAULTS
  • Avec ses autres contraintes :
    • INCLUDING CONSTRAINTS
  • Avec ses index :
    • INCLUDING INDEXES

Modification d'une table

  • ALTER TABLE
  • DĂ©finition de la table
    • renommage de la table
    • ajout/modification/suppression d'une colonne
    • dĂ©placement dans un schĂ©ma diffĂ©rent
    • changement du propriĂ©taire
  • DĂ©finition des colonnes
    • renommage d'une colonne
    • changement de type d'une colonne
  • DĂ©finition des contraintes
    • ajout/suppression d'une contrainte

Suppression d'une table

  • Supprimer une table :

    DROP TABLE nom_table;
  • Supprimer une table et tous les objets dĂ©pendants :

    DROP TABLE nom_table CASCADE;

Contraintes d'intégrité

  • ACID
    • CohĂ©rence
    • une transaction amène la base d'un Ă©tat stable Ă  un autre
  • Assurent la cohĂ©rence des donnĂ©es
    • unicitĂ© des enregistrements
    • intĂ©gritĂ© rĂ©fĂ©rentielle
    • vĂ©rification des valeurs
    • identitĂ© des enregistrements
    • règles sĂ©mantiques

Clés primaires

  • Identifie une ligne de manière unique
  • Une seule clĂ© primaire par table
  • Une ou plusieurs colonnes
  • Ă€ choisir parmi les clĂ©s candidates
    • parfois, utiliser une clĂ© artificielle

Déclaration d'une clé primaire

Construction :

[CONSTRAINT nom_contrainte]
PRIMARY KEY ( nom_colonne [, ... ] )

Contrainte d'unicité

  • Garantie l'unicitĂ© des valeurs d'une ou plusieurs colonnes
  • Permet les valeurs NULL
  • Clause UNIQUE
  • Contrainte UNIQUE != index UNIQUE

Déclaration d'une contrainte d'unicité

Construction :

[ CONSTRAINT nom_contrainte]
{ UNIQUE ( nom_colonne [, ... ] )

Intégrité référentielle

  • Contrainte d'intĂ©gritĂ© rĂ©fĂ©rentielle
    • ou ClĂ© Ă©trangère
  • RĂ©fĂ©rence une clĂ© primaire ou un groupe de colonnes UNIQUE et NOT NULL
  • Garantie l'intĂ©gritĂ© des donnĂ©es
  • FOREIGN KEY

Exemple

Schéma base cave

Déclaration d'une clé étrangère

[ CONSTRAINT nom_contrainte ] FOREIGN KEY ( nom_colonne [, ...] )
    REFERENCES table_reference [ (colonne_reference [, ... ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE action ] [ ON UPDATE action ] }

Vérification simple ou complète

  • VĂ©rification complète ou partielle d'une clĂ© Ă©trangère
  • MATCH
    • MATCH FULL (complète)
    • MATCH SIMPLE (partielle)

Colonnes d'identité

  • IdentitĂ© d'un enregistrement
  • GENERATED ... AS IDENTITY
    • ALWAYS
    • BY DEFAULT
  • PrĂ©fĂ©rer Ă  serial
  • UnicitĂ© non garantie sans contrainte explicite !

Mise à jour de la clé primaire

  • Que faire en cas de mise Ă  jour d'une clĂ© primaire ?
    • les clĂ©s Ă©trangères seront fausses
  • ON UPDATE
  • ON DELETE
  • DĂ©finition d'une action au niveau de la clĂ© Ă©trangère
    • interdiction
    • propagation de la mise Ă  jour
    • NULL
    • valeur par dĂ©faut

VĂ©rifications

  • PrĂ©sence d'une valeur
    • NOT NULL
  • VĂ©rification de la valeur d'une colonne
    • CHECK

Vérifications différés

  • VĂ©rifications après chaque ordre SQL
    • problèmes de cohĂ©rence
  • DiffĂ©rer les vĂ©rifications de contraintes
    • clause DEFERRABLE, NOT DEFERRABLE
    • INITIALLY DEFERED, INITIALLY IMMEDIATE

VĂ©rifications plus complexes

  • Un trigger
    • si une contrainte porte sur plusieurs tables
    • si sa vĂ©rification nĂ©cessite une sous-requĂŞte
  • PrĂ©fĂ©rer les contraintes dĂ©claratives

DML : mise à jour des données

  • SELECT peut lire les donnĂ©es d'une table ou plusieurs tables
    • mais ne peut pas les mettre Ă  jour
  • Ajout de donnĂ©es dans une table
    • INSERT
  • Modification des donnĂ©es d'une table
    • UPDATE
  • Suppression des donnĂ©es d'une table
    • DELETE

Ajout de données : INSERT

  • Ajoute des lignes Ă  partir des donnĂ©es de la requĂŞte
  • Ajoute des lignes Ă  partir d'une requĂŞte SELECT
  • Syntaxe :
INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
    { liste_valeurs | requete }

INSERT avec liste d'expressions

INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
    VALUES ( { expression | DEFAULT } [, ...] ) [, ...]

INSERT Ă  partir d'un SELECT

INSERT INTO nom_table [ ( nom_colonne [, ...] ) ]
    requĂŞte

INSERT et colonnes implicites

  • L'ordre physique peut changer dans le temps
    • rĂ©sultats incohĂ©rents
    • requĂŞtes en erreurs

Mise à jour de données : UPDATE

  • Ordre UPDATE
  • Met Ă  jour une ou plusieurs colonnes d'une mĂŞme ligne
    • Ă  partir des valeurs de la requĂŞte
    • Ă  partir des anciennes valeurs
    • Ă  partir d'une requĂŞte SELECT
    • Ă  partir de valeurs d'une autre table

Construction d'UPDATE

UPDATE nom_table
    SET
    {
     nom_colonne = { expression | DEFAULT }
    |
     ( nom_colonne [, ...] ) = ( { expression | DEFAULT } [, ...] )
    } [, ...]
    [ FROM liste_from ]
    [ WHERE condition | WHERE CURRENT OF nom_curseur ]

Suppression de données : DELETE

  • Supprime les lignes rĂ©pondant au prĂ©dicat
  • Syntaxe :
DELETE FROM nom_table [ [ AS ] alias ]
    [ WHERE condition

Clause RETURNING

  • SpĂ©cifique Ă  PostgreSQL
  • Permet de retourner les lignes complètes ou partielles rĂ©sultants de INSERT, UPDATE ou DELETE
  • Syntaxe :
requete_sql RETURNING ( * | expression )

Transactions

  • ACID
    • atomicitĂ©
    • un traitement se fait en entier ou pas du tout
  • TCL pour Transaction Control Language
    • valide une transaction
    • annule une transaction
    • points de sauvegarde

Auto-commit et transactions

  • Par dĂ©faut, PostgreSQL fonctionne en auto-commit
    • Ă  moins d'ouvrir explicitement une transaction
  • Ouvrir une transaction
    • BEGIN TRANSACTION

Validation ou annulation d'une transaction

  • Valider une transaction
    • COMMIT
  • Annuler une transaction
    • ROLLBACK
  • Sans validation, une transaction est forcĂ©ment annulĂ©e

Programmation

  • Certains langages implĂ©mentent des mĂ©thodes de gestion des transactions
    • PHP, Java, etc.
  • Utiliser ces mĂ©thodes prioritairement

Points de sauvegarde

  • Certains traitements dans une transaction peuvent ĂŞtre annulĂ©s
    • mais la transaction est atomique
  • DĂ©finir un point de sauvegarde
    • SAVEPOINT nom_savepoint
  • Valider le traitement depuis le dernier point de sauvegarde
    • RELEASE SAVEPOINT nom_savepoint
  • Annuler le traitement depuis le dernier point de sauvegarde
    • ROLLBACK TO SAVEPOINT nom_savepoint

Conclusion

  • SQL : toujours un traitement d'ensembles d'enregistrements
    • c'est le cĂ´tĂ© relationnel
  • Pour les dĂ©finitions d'objets
    • CREATE, ALTER, DROP
  • Pour les donnĂ©es
    • INSERT, UPDATE, DELETE

Questions

N'hésitez pas, c'est le moment !

Travaux Pratiques

Plus loin avec SQL

Préambule

  • Après la dĂ©finition des objets, leur lecture et leur Ă©criture
  • Aller plus loin dans l'Ă©criture de requĂŞtes
    • avec les jointures
    • avec les requĂŞtes intĂ©grĂ©es
  • Valeur NULL
  • AgrĂ©gats, GROUP BY, HAVING
  • Sous-requĂŞtes
  • Jointures
  • Expression conditionnelle CASE
  • OpĂ©rateurs ensemblistes : UNION, EXCEPT, INTERSECT

Objectifs

  • Comprendre l'intĂ©rĂŞt du NULL
  • Savoir Ă©crire des requĂŞtes complexes

Valeur NULL

  • Comment reprĂ©senter une valeur que l'on ne connait pas ?
    • Valeur NULL
  • Trois sens possibles pour NULL :
    • valeur inconnue
    • valeur inapplicable
    • absence de valeur
  • Logique 3 Ă©tats

Avertissement

  • Chris J. Date a Ă©crit :
    • La valeur NULL telle qu'elle est implĂ©mentĂ©e dans SQL peut poser plus de problèmes qu'elle n'en rĂ©sout. Son comportement est parfois Ă©trange et est source de nombreuses erreurs et de confusions.
  • Éviter d'utiliser NULL le plus possible
    • utiliser NULL correctement lorsqu'il le faut

Assignation de NULL

  • Assignation de NULL pour INSERT et UPDATE
  • Explicitement :
    • NULL est indiquĂ© explicitement dans les assignations
  • Implicitement :
    • la colonne n'est pas affectĂ©e par INSERT
    • et n'a pas de valeur par dĂ©faut
  • EmpĂŞcher la valeur NULL
    • contrainte NOT NULL

Calculs avec NULL

  • Utilisation dans un calcul
    • propagation de NULL
  • NULL est inapplicable
    • le rĂ©sultat vaut NULL

NULL et les prédicats

  • Dans un prĂ©dicat du WHERE :
    • opĂ©rateur IS NULL ou IS NOT NULL
  • AND :
    • vaut false si NULL AND false
    • vaut NULL si NULL AND true ou NULL AND NULL
  • OR :
    • vaut true si NULL OR true
    • vaut NULL si NULL OR false ou NULL OR NULL

NULL et les agrégats

  • OpĂ©rateurs d'agrĂ©gats
    • ignorent NULL
    • sauf count(*)

COALESCE

  • Remplacer NULL par une autre valeur
    • COALESCE(attribut, ...);

Agrégats

  • Regroupement de donnĂ©es
  • Calculs d'agrĂ©gats

Regroupement de données

  • Regroupement de donnĂ©es :

    GROUP BY expression [, ...]
  • Chaque groupe de donnĂ©es est ensuite reprĂ©sentĂ© sur une seule ligne
  • Permet d'appliquer des calculs sur les ensembles regroupĂ©s
    • comptage, somme, moyenne, etc.

Calculs d'agrégats

  • Effectue un calcul sur un ensemble de valeurs
    • somme, moyenne, etc.
  • Retourne NULL si l'ensemble est vide
    • sauf count()

Agrégats simples

  • Comptage :

    count(expression)
  • compte les lignes : count(*)
    • compte les valeurs renseignĂ©es : count(colonne)
  • Valeur minimale :

    min(expression)
  • Valeur maximale :

    max(expression)

Calculs d'agrégats

  • Moyenne :

    avg(expression)
  • Somme :

    sum(expression)
  • Écart-type :

    stddev(expression)
  • Variance :

    variance(expression)

Agrégats sur plusieurs colonnes

  • Possible d'avoir plusieurs paramètres sur la mĂŞme fonction d'agrĂ©gat
  • Quelques exemples
    • pente, regr_slope(Y,X)
    • intersection avec l'axe des ordonnĂ©es, regr_intercept(Y,X)
    • indice de corrĂ©lation, corr (Y,X)

Clause HAVING

  • Filtrer sur des regroupements
    • HAVING
  • WHERE s'applique sur les lignes lues
  • HAVING s'applique sur les lignes groupĂ©es

Sous-requĂŞtes

  • CorrĂ©lation requĂŞte/sous-requĂŞte
  • Sous-requĂŞtes retournant une seule ligne
  • Sous-requĂŞtes retournant une liste de valeur
  • Sous-requĂŞtes retournant un ensemble
  • Sous-requĂŞtes retournant un ensemble vide ou non-vide

Corrélation requête/sous-requête

  • Fait rĂ©fĂ©rence Ă  la requĂŞte principale
  • Peut utiliser une valeur issue de la requĂŞte principale

Qu'est-ce qu'une sous-requĂŞte ?

  • Une requĂŞte imbriquĂ©e dans une autre requĂŞte
  • Le rĂ©sultat de la requĂŞte principale dĂ©pend du rĂ©sultat de la sous-requĂŞte
  • EncadrĂ©e par des parenthèses : ( et )

Utiliser une seule ligne

  • La sous-requĂŞte ne retourne qu'une seule ligne
    • sinon une erreur est levĂ©e
  • PositionnĂ©e
    • au niveau de la liste des expressions retournĂ©es par SELECT
    • au niveau de la clause WHERE
    • au niveau d'une clause HAVING

Utiliser une liste de valeurs

  • La sous-requĂŞte retourne
    • plusieurs lignes
    • sur une seule colonne
  • PositionnĂ©e
    • avec une clause IN
    • avec une clause ANY
    • avec une clause ALL

Clause IN

expression IN (sous-requete)
  • L'expression de gauche est Ă©valuĂ©e et vĂ©rifiĂ©e avec la liste de valeurs de droite
  • IN vaut true
    • si l'expression de gauche correspond Ă  un Ă©lĂ©ment de la liste de droite
  • IN vaut false
    • si aucune correspondance n'est trouvĂ©e et la liste ne contient pas NULL
  • IN vaut NULL
    • si l'expression de gauche vaut NULL
    • si aucune valeur ne correspond et la liste contient NULL

Clause NOT IN

expression NOT IN (sous-requete)
  • L'expression de droite est Ă©valuĂ©e et vĂ©rifiĂ©e avec la liste de valeurs de gauche
  • NOT IN vaut true
    • si aucune correspondance n'est trouvĂ©e et la liste ne contient pas NULL
  • NOT IN vaut false
    • si l'expression de gauche correspond Ă  un Ă©lĂ©ment de la liste de droite
  • NOT IN vaut NULL
    • si l'expression de gauche vaut NULL
    • si aucune valeur ne correspond et la liste contient NULL

Clause ANY

expression operateur ANY (sous-requete)
  • L'expression de gauche est comparĂ©e au rĂ©sultat de la sous-requĂŞte avec l'opĂ©rateur donnĂ©
  • La ligne de gauche est retournĂ©e
    • si le rĂ©sultat d'au moins une comparaison est vraie
  • La ligne de gauche n'est pas retournĂ©e
    • si aucun rĂ©sultat de la comparaison n'est vrai
    • si l'expression de gauche vaut NULL
    • si la sous-requĂŞte ramène un ensemble vide

Clause ALL

expression operateur ALL (sous-requete)
  • L'expression de gauche est comparĂ©e Ă  tous les rĂ©sultats de la sous-requĂŞte avec l'opĂ©rateur donnĂ©
  • La ligne de gauche est retournĂ©e
    • si tous les rĂ©sultats des comparaisons sont vrais
    • si la sous-requĂŞte retourne un ensemble vide
  • La ligne de gauche n'est pas retournĂ©e
    • si au moins une comparaison est fausse
    • si au moins une comparaison est NULL

Utiliser un ensemble

  • La sous-requĂŞte retourne
    • plusieurs lignes
    • sur plusieurs colonnes
  • PositionnĂ©e au niveau de la clause FROM
  • NommĂ©e avec un alias de table

Clause EXISTS

EXISTS (sous-requete)
  • IntĂ©ressant avec une corrĂ©lation
  • La clause EXISTS vĂ©rifie la prĂ©sence ou l'absence de rĂ©sultats
    • vrai si l'ensemble est non vide
    • faux si l'ensemble est vide

Jointures

  • Produit cartĂ©sien
  • Jointure interne
  • Jointures externes
  • Jointure ou sous-requĂŞte ?

Produit cartésien

  • Clause CROSS JOIN
  • RĂ©alise toutes les combinaisons entre les lignes d'une table et les lignes d'une autre
  • Ă€ Ă©viter dans la mesure du possible
    • peu de cas d'utilisation
    • peu performant

Jointure interne

  • Clause INNER JOIN
    • meilleure lisibilitĂ©
    • facilite le travail de l'optimiseur
  • Joint deux tables entre elles
    • Selon une condition de jointure
Schéma de jointure interne
Schéma de jointure interne

Syntaxe d'une jointure interne

  • Condition de jointure par prĂ©dicats :

    table1 [INNER] JOIN table2 ON prédicat [...]
  • Condition de jointure implicite par liste des colonnes impliquĂ©es :

    table1 [INNER] JOIN table2 USING (colonne [, ...])
  • Liste des colonnes implicites :

    table1 NATURAL [INNER] JOIN table2

Jointure externe

  • Jointure externe Ă  gauche
    • ramène le rĂ©sultat de la jointure interne
    • ramène l'ensemble de la table de gauche qui ne peut ĂŞtre joint avec la table de droite
    • les attributs de la table de droite sont alors NULL
Schéma de jointure externe gauche
Schéma de jointure externe gauche

Jointure externe - 2

  • Jointure externe Ă  droite
    • ramène le rĂ©sultat de la jointure interne
    • ramène l'ensemble de la table de droite qui ne peut ĂŞtre joint avec la table de gauche
    • les attributs de la table de gauche sont alors NULL
Schéma de jointure externe droite
Schéma de jointure externe droite

Jointure externe complète

  • Ramène le rĂ©sultat de la jointure interne
  • Ramène l'ensemble de la table de gauche qui ne peut ĂŞtre joint avec la table de droite
    • les attributs de la table de droite sont alors NULL
  • Ramène l'ensemble de la table de droite qui ne peut ĂŞtre joint avec la table de gauche
    • les attributs de la table de gauche sont alors NULL

Syntaxe d'une jointure externe Ă  gauche

  • Condition de jointure par prĂ©dicats :

    table1 LEFT [OUTER] JOIN table2 ON prédicat [...]
  • Condition de jointure implicite par liste des colonnes impliquĂ©es :

    table1 LEFT [OUTER] JOIN table2 USING (colonne [, ...])
  • Liste des colonnes implicites :

    table1 NATURAL LEFT [OUTER] JOIN table2

Syntaxe d'une jointure externe Ă  droite

  • Condition de jointure par prĂ©dicats :

    table1 RIGHT [OUTER] JOIN table2 ON prédicat [...]
  • Condition de jointure implicite par liste des colonnes impliquĂ©es :

    table1 RIGHT [OUTER] JOIN table2 USING (colonne [, ...])
  • Liste des colonnes implicites :

    table1 NATURAL RIGHT [OUTER] JOIN table2

Syntaxe d'une jointure externe complète

  • Condition de jointure par prĂ©dicats :

    table1 FULL OUTER JOIN table2 ON prédicat [...]
  • Condition de jointure implicite par liste des colonnes impliquĂ©es :

    table1 FULL OUTER JOIN table2 USING (colonne [, ...])
  • Liste des colonnes implicites :

    table1 NATURAL FULL OUTER JOIN table2

Jointure ou sous-requĂŞte ?

  • Jointures
    • algorithmes très efficaces
    • ne gèrent pas tous les cas
  • Sous-requĂŞtes
    • parfois peu performantes
    • rĂ©pondent Ă  des besoins non couverts par les jointures

Expressions CASE

  • Équivalent Ă  l'instruction switch en C ou Java
  • EmpruntĂ© au langage Ada
  • Retourne une valeur en fonction du rĂ©sultat de tests

CASE simple

CASE expression
     WHEN valeur THEN expression
     WHEN valeur THEN expression
     (...)
     ELSE expression
 END

CASE sur expressions

CASE WHEN expression THEN expression
     WHEN expression THEN expression
     (...)
     ELSE expression
 END

Spécificités de CASE

  • Comportement procĂ©dural
    • les expressions sont Ă©valuĂ©es dans l'ordre d'apparition
  • Transtypage
    • le type du retour de l'expression dĂ©pend du type de rang le plus Ă©levĂ© de toute l'expression
  • Imbrication
    • des expressions CASE Ă  l'intĂ©rieur d'autres expressions CASE
  • Clause ELSE
    • recommandĂ©

Opérateurs ensemblistes

  • UNION
  • INTERSECT
  • EXCEPT

Regroupement de deux ensembles

  • Regroupement avec dĂ©doublonnage :

    requete_select1 UNION requete_select2
  • Regroupement sans dĂ©doublonnage :

    requete_select1 UNION ALL requete_select2

Intersection de deux ensembles

  • Intersection de deux ensembles avec dĂ©doublonnage :

    requete_select1 INTERSECT requete_select2
  • Intersection de deux ensembles sans dĂ©doublonnage :

    requete_select1 INTERSECT ALL requete_select2

Différence entre deux ensembles

  • DiffĂ©rence entre deux ensembles avec dĂ©doublonnage :

    requete_select1 EXCEPT requete_select2
  • DiffĂ©rence entre deux ensembles sans dĂ©doublonnage :

    requete_select1 EXCEPT ALL requete_select2

Conclusion

  • PossibilitĂ© d'Ă©crire des requĂŞtes complexes
  • C'est lĂ  oĂą PostgreSQL est le plus performant

Questions

N'hésitez pas, c'est le moment !

Travaux Pratiques

Approfondissement SQL

Préambule

  • Aller encore plus loin
    • tout en Ă©vitant le pire
  • ApprĂ©hender de nouveaux objets
    • fonctions utiles
    • vues
  • Utiliser des requĂŞtes prĂ©parĂ©es
  • Fonctions de base
  • Vues
  • RequĂŞtes prĂ©parĂ©es
  • Index
  • Ce qu'il ne faut pas faire

Objectifs

  • Utiliser des objets avancĂ©es
  • Gagner en performance
  • Éviter les pièges les plus frĂ©quents

Fonctions de base

  • Transtypage
  • Manipulation de chaines
  • Manipulation de types numĂ©riques
  • Manipulation de dates
  • GĂ©nĂ©ration de jeu de donnĂ©es

Transtypage

  • Conversion d'un type de donnĂ©es vers un autre type de donnĂ©es
  • CAST (expression AS type)
  • expression::type

Opérations simples sur les chaînes

  • ConcatĂ©nation : chaĂ®ne1 || chaĂ®ne2
  • Longueur de la chaĂ®ne : char_length(chaĂ®ne)
  • Conversion en minuscules : lower(chaĂ®ne)
  • Conversion en majuscules : upper(chaĂ®ne)

Manipulations de chaînes

  • Extrait une chaĂ®ne Ă  partir d'une autre : substring(chaĂ®ne [from int] [for int])
  • Emplacement d'une sous-chaĂ®ne : position(sous-chaĂ®ne in chaĂ®ne)

Manipulation de types numériques

  • OpĂ©rations arithmĂ©tiques
  • Manipulation de types numĂ©riques
  • GĂ©nĂ©ration de donnĂ©es

Opérations arithmétiques

  • Addition : +
  • Soustraction : -
  • Multiplication : *
  • Division : /
  • Reste (modulo) : %

Fonctions numériques courantes

  • Arrondi : round(numeric)

  • Troncature : trunc(numeric [, precision])

  • Entier le plus petit : floor(numeric)

  • Entier le plus grand : ceil(numeric)

Génération de données

  • GĂ©nĂ©rer une suite d'entiers : generate_series(borne_debut, borne_fin, intervalle)

  • GĂ©nĂ©rer un nombre alĂ©atoire : random()

Manipulation de dates

  • Obtenir la date et l'heure courante
  • Manipuler des dates
  • OpĂ©rations arithmĂ©tiques
  • Formatage de donnĂ©es

Date et heure courante

  • Retourne la date courante : current_date
  • Retourne l'heure courante : current_time
  • Retourne la date et l'heure courante : current_timestamp

Manipulation des données

  • Ă‚ge
    • Par rapport Ă  la date courante : age(timestamp)
    • Par rapport Ă  une date de rĂ©fĂ©rence : age(timestamp, timestamp)

Tronquer et extraire

  • Troncature d'une date : date_trunc(text, timestamp)
  • Exemple : date_trunc('month' from date_naissance)
  • Extrait une composante de la date : extract(text, timestamp)
  • Exemple : extract('year' from date_naissance)

Arithmétique sur les dates

  • OpĂ©rations arithmĂ©tiques sur timestamp, time ou date
    • date/time - date/time = interval
    • date/time + time = date/time
    • date/time + interval = date/time
  • OpĂ©rations arithmĂ©tiques sur interval
    • interval * numeric = interval
    • interval / numeric = interval
    • interval + interval = interval

Date vers chaîne

  • Conversion d'une date en chaĂ®ne de caractères : to_char(timestamp, text)
  • Exemple : to_char(current_timestamp, 'DD/MM/YYYY HH24:MI:SS')

Chaîne vers date

  • Conversion d'une chaĂ®ne de caractères en date : to_date(text, text) to_date('05/12/2000', 'DD/MM/YYYY')
  • Conversion d'une chaĂ®ne de caractères en timestamp : to_timestamp(text, text) to_timestamp('05/12/2000 12:00:00', 'DD/MM/YYYY HH24:MI:SS')
  • Paramètre datestyle

Génération de données

  • GĂ©nĂ©rer une suite de timestamp : generate_series(timestamp_debut, timestamp_fin, intervalle)

Vues

  • Tables virtuelles
    • dĂ©finies par une requĂŞte SELECT
    • dĂ©finition stockĂ©e dans le catalogue de la base de donnĂ©es
  • Objectifs
    • masquer la complexitĂ© d'une requĂŞte
    • masquer certaines donnĂ©es Ă  l'utilisateur

Création d'une vue

  • Une vue porte un nom au mĂŞme titre qu'une table
    • elle sera nommĂ©e avec les mĂŞmes règles
  • Ordre de crĂ©ation d'une vue : CREATE VIEW vue (colonne ...) AS SELECT ...

Lecture d'une vue

  • Une vue est lue comme une table
    • SELECT * FROM vue;

SĂ©curisation d'une vue

  • SĂ©curiser une vue
    • droits avec GRANT et REVOKE
  • Utiliser les vues comme moyen de filtrer les lignes est dangereux
    • option security_barrier

Mise Ă  jour des vues

  • Trigger INSTEAD OF
  • Updatable view (PostgreSQL 9.3)

Mauvaises utilisations

  • ProlifĂ©ration des vues
    • crĂ©er une vue doit se justifier
    • ne pas crĂ©er une vue par table

Requêtes préparées

  • ExĂ©cution en deux temps
    • prĂ©paration du plan d'exĂ©cution de la requĂŞte
    • exĂ©cution de la requĂŞte en utilisant le plan prĂ©parĂ©
  • Objectif :
    • Ă©viter simplement les injections SQL
    • amĂ©liorer les performances

Utilisation

  • PREPARE, prĂ©paration du plan d'exĂ©cution d'une requĂŞte
  • EXECUTE, passage des paramètres de la requĂŞte et exĂ©cution rĂ©elle
  • L'implĂ©mentation dĂ©pend beaucoup du langage de programmation utilisĂ©
    • le connecteur JDBC supporte les requĂŞtes prĂ©parĂ©es
    • le connecteur PHP/PDO Ă©galement

Indexation

  • Comment gagner en performance
  • Index
    • reprĂ©sentation valeur / pointeur
    • arbre de valeurs

Créer un index

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ]
  ON table_name
  ( { column_name | ( expression ) }
    [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
  [ TABLESPACE tablespace_name ]
  [ WHERE predicate ]

Lecture avec index

  • L'index permet une recherche plus rapide
  • Il n'a besoin de lire que quelques blocs
    • et non pas la table entière

Insertion avec index

  • AccĂ©lère la recherche
    • mais ralentit les Ă©critures
  • Une Ă©criture dans la table doit mettre Ă  jour l'index
  • Faire attention Ă  ne pas crĂ©er des index inutiles

Tri avec un index

  • Un index ne sert pas qu'Ă  la recherche
  • Les donnĂ©es Ă©tant triĂ©es, il sert aussi Ă  accĂ©lĂ©rer les tris

Index partiel

  • N'indexer qu'une partie des donnĂ©es
  • RequĂŞte typique : SELECT * FROM taches WHERE fait IS false ORDER BY date_rendu;
  • Index typique : CREATE INDEX ON taches(date_rendu) WHERE fait IS false;

Index fonctionnel

  • Indexer le rĂ©sultat d'une expression
  • Fonctions immuables seulement
  • RequĂŞte typique : SELECT * FROM employes WHERE upper(nom)='DUPONT';
  • Index typique : CREATE INDEX ON employes(upper(nom));

Ce qu'il ne faut pas faire

  • ModĂ©lisation
  • Écriture de requĂŞtes
  • Conception de l'application

Absence de contraintes

  • Concerne surtout les clĂ©s Ă©trangères
  • Parfois (souvent?) ignorĂ©es pour diverses raisons :
    • performances
    • flexibilitĂ© du modèle de donnĂ©es
    • compatibilitĂ© avec d'autres SGBD
    • hĂ©ritage de MySQL/MyISAM
    • commoditĂ© de dĂ©veloppement
  • ConsĂ©quences
    • problèmes d'intĂ©gritĂ© des donnĂ©es
    • procĂ©dures de vĂ©rification de cohĂ©rence des donnĂ©es

Stockage EAV

  • EntitĂ©-Attribut-Valeur
  • Pourquoi
    • flexibilitĂ© du modèle de donnĂ©es
    • adapter sans dĂ©lai ni surcoĂ»t le modèle de donnĂ©es
  • ConsĂ©quences
    • crĂ©ation d'une table : identifiant, nom_attribut, valeur
    • requĂŞtes abominables et coĂ»teuses
  • Solutions
    • revenir sur la conception du modèle de donnĂ©es
    • utiliser un type de donnĂ©es plus adaptĂ© (hstore, jsonb)

Attributs multi-colonnes

  • Pourquoi
    • stocker plusieurs attributs pour une mĂŞme ligne
    • exemple : les diffĂ©rents numĂ©ros de tĂ©lĂ©phone d'une personne
  • Pratique courante
    • ajouter plusieurs colonnes portant le mĂŞme nom
  • ConsĂ©quences
    • et s'il faut rajouter encore une colonne ?
    • maĂ®trise de l'unicitĂ© des valeurs
    • requĂŞtes complexes Ă  maintenir
  • Solutions
    • crĂ©er une table de dĂ©pendance
    • utiliser un type tableau

Choix des types de données

  • Objectif
    • reprĂ©senter des valeurs dĂ©cimales
  • Pratique courante
    • utiliser le type float ou double
  • Problèmes :
    • les types flottants ne stockent qu'une approximation de la valeur reprĂ©sentĂ©e
    • les erreurs d'arrondis se multiplient
    • les requĂŞtes produisent des rĂ©sultats faux
  • Solutions
    • privilĂ©gier le type numeric(x, y) pour les calculs prĂ©cis (financiers notamment)

Problèmes courants d'écriture de requêtes

  • Utilisation de NULL
  • Ordre implicite des colonnes
  • RequĂŞtes spaghetti
  • Moteur de recherche avec LIKE

Ordre implicite des colonnes

  • Objectif
    • s'Ă©conomiser d'Ă©crire la liste des colonnes dans une requĂŞte
  • Problèmes
    • si l'ordre des colonnes change, les rĂ©sultats changent
    • rĂ©sultats faux
    • donnĂ©es corrompues
  • Solutions
    • nommer les colonnes impliquĂ©es

Code spaghetti

Le problème est similaire à tout autre langage :

  • Code spaghetti pour le SQL
    • Écriture d'une requĂŞte Ă  partir d'une autre requĂŞte
    • Ou Ă©volution d'une requĂŞte au fil du temps avec des ajouts
  • Vite ingĂ©rable
    • Ne pas hĂ©siter Ă  reprendre la requĂŞte Ă  zĂ©ro, en repensant sa sĂ©mantique
    • Souvent, un changement de spĂ©cification est un changement de sens, au niveau relationnel, de la requĂŞte
    • Ne pas la patcher !

Recherche textuelle

  • Objectif
    • ajouter un moteur de recherche Ă  l'application
  • Pratique courante
    • utiliser l'opĂ©rateur LIKE
  • Problèmes
    • requiert des index spĂ©cialisĂ©s
    • recherche uniquement le terme exact
  • Solution
    • utiliser Full Text Search

Conclusion

  • Des objets de plus en plus complexes
    • mais performants
    • et remplissant un besoin
  • Des conseils
    • pour amĂ©liorer les performances
    • et pour Ă©viter les pièges

Questions

N'hésitez pas, c'est le moment !

Travaux Pratiques

Comprendre EXPLAIN

PostgreSQL
PostgreSQL

Introduction

  • Le matĂ©riel, le système et la configuration sont importants pour les performances
  • Mais il est aussi essentiel de se prĂ©occuper des requĂŞtes et de leurs performances

Au menu

  • ExĂ©cution globale d'une requĂŞte
  • Planificateur : utilitĂ©, statistiques et configuration
  • EXPLAIN
  • NĹ“uds d'un plan
  • Outils

Exécution globale d'une requête

  • L'exĂ©cution peut se voir sur deux niveaux
    • Niveau système
    • Niveau SGBD
  • De toute façon, composĂ©e de plusieurs Ă©tapes

Niveau système

  • Le client envoie une requĂŞte au serveur de bases de donnĂ©es
  • Le serveur l'exĂ©cute
  • Puis il renvoie le rĂ©sultat au client

Niveau SGBD

Traitement d'une requĂŞteSQL

Exceptions

  • RequĂŞtes DDL
  • Instructions TRUNCATE et COPY
  • Pas de rĂ©Ă©criture, pas de plans d'exĂ©cution... une exĂ©cution directe

Quelques définitions

  • PrĂ©dicat
    • filtre de la clause WHERE
  • SĂ©lectivitĂ©
    • pourcentage de lignes retournĂ©es après application d'un prĂ©dicat
  • CardinalitĂ©
    • nombre de lignes d'une table
    • nombre de lignes retournĂ©es après filtrage

Requête étudiée

Cette requĂŞte d'exemple :

SELECT matricule, nom, prenom, nom_service, fonction, localisation
  FROM employes emp
  JOIN services ser ON (emp.num_service = ser.num_service)
 WHERE ser.localisation = 'Nantes';

Plan de la requête étudiée

L'objet de ce module est de comprendre son plan d'exécution :

 Hash Join  (cost=1.06..2.29 rows=4 width=48)
   Hash Cond: (emp.num_service = ser.num_service)
   ->  Seq Scan on employes emp  (cost=0.00..1.14 rows=14 width=35)
   ->  Hash  (cost=1.05..1.05 rows=1 width=21)
         ->  Seq Scan on services ser  (cost=0.00..1.05 rows=1 width=21)
               Filter: ((localisation)::text = 'Nantes'::text)

Planificateur

  • ChargĂ© de sĂ©lectionner le meilleur plan d'exĂ©cution
  • Énumère tous les plans d'exĂ©cution
    • Tous ou presque...
  • Calcule leur coĂ»t suivant des statistiques, un peu de configuration et beaucoup de règles
  • SĂ©lectionne le meilleur (le moins coĂ»teux)

Utilité

  • SQL est un langage dĂ©claratif
  • Une requĂŞte dĂ©crit le rĂ©sultat Ă  obtenir
    • Mais pas la façon de l'obtenir
  • C'est au planificateur de dĂ©duire le moyen de parvenir au rĂ©sultat demandĂ©

Règles

  • 1ère règle : RĂ©cupĂ©rer le bon rĂ©sultat
  • 2è règle : Le plus rapidement possible
    • En minimisant les opĂ©rations disques
    • En prĂ©fĂ©rant les lectures sĂ©quentielles
    • En minimisant la charge CPU
    • En minimisant l'utilisation de la mĂ©moire

Outils de l'optimiseur

  • L'optimiseur s'appuie sur :
    • un mĂ©canisme de calcul de coĂ»ts
    • des statistiques sur les donnĂ©es
    • le schĂ©ma de la base de donnĂ©es

Optimisations

  • Ă€ partir du modèle de donnĂ©es
    • suppression de jointures externes inutiles
  • Transformation des sous-requĂŞtes
    • certaines sous-requĂŞtes transformĂ©es en jointures
  • Appliquer les prĂ©dicats le plus tĂ´t possible
    • rĂ©duit le jeu de donnĂ©es manipulĂ©
  • Intègre le code des fonctions SQL simples (inline)
    • Ă©vite un appel de fonction coĂ»teux

DĂ©cisions

  • StratĂ©gie d'accès aux lignes
    • Par parcours d'une table, d'un index, de TID, etc
  • StratĂ©gie d'utilisation des jointures
    • Ordre des jointures
    • Type de jointure (Nested Loop, Merge/Sort Join, Hash Join)
    • Ordre des tables jointes dans une mĂŞme jointure
  • StratĂ©gie d'agrĂ©gation
    • Brut, triĂ©, hachĂ©

Mécanisme de coûts

  • Modèle basĂ© sur les coĂ»ts
    • quantifier la charge pour rĂ©pondre Ă  une requĂŞte
  • Chaque opĂ©ration a un coĂ»t :
    • lire un bloc selon sa position sur le disque
    • manipuler une ligne issue d'une lecture de table ou d'index
    • appliquer un opĂ©rateur

Coûts unitaires

  • L'optimiseur a besoin de connaĂ®tre :
    • le coĂ»t relatif d'un accès sĂ©quentiel au disque.
    • le coĂ»t relatif d'un accès alĂ©atoire au disque.
    • le coĂ»t relatif de la manipulation d'une ligne en mĂ©moire.
    • le coĂ»t de traitement d'une donnĂ©e issue d'un index.
    • le coĂ»t d'application d'un opĂ©rateur.
    • le coĂ»t de la manipulation d'une ligne en mĂ©moire pour un parcours parallèle parallĂ©lisĂ©.
    • le coĂ»t de mise en place d'un parcours parallĂ©lisĂ©.

Statistiques

  • Toutes les dĂ©cisions du planificateur se basent sur les statistiques
    • Le choix du parcours
    • Comme le choix des jointures
  • Statistiques mises Ă  jour avec ANALYZE
  • Sans bonnes statistiques, pas de bons plans

Utilisation des statistiques

  • L'optimiseur utilise les statistiques pour dĂ©terminer :
    • la cardinalitĂ© d'un filtre -> quelle stratĂ©gie d'accès
    • la cardinalitĂ© d'une jointure -> quel algorithme de jointure
    • la cardinalitĂ© d'un regroupement -> quel algorithme de regroupement

Statistiques : table et index

  • Taille
  • CardinalitĂ©
  • StockĂ© dans pg_class
    • relpages et reltuples

Statistiques : mono-colonne

  • Nombre de valeurs distinctes
  • Nombre d'Ă©lĂ©ments qui n'ont pas de valeur (NULL)
  • Largeur d'une colonne
  • Distribution des donnĂ©es
    • tableau des valeurs les plus frĂ©quentes
    • histogramme de rĂ©partition des valeurs

Stockage des statistiques mono-colonne

  • Les informations statistiques vont dans la table pg_statistic
    • mais elle est difficile Ă  comprendre
    • mieux vaut utiliser la vue pg_stats
    • une table vide n'a pas de statistiques
  • Taille et cardinalitĂ© dans pg_class
    • colonnes relpages et reltuples

Vue pg_stats

  • Une ligne par colonne de chaque table
  • 3 colonnes d'identification
    • schemaname, tablename, attname
  • 8 colonnes d'informations statistiques
    • inherited, null_frac, avg_width, n_distinct
    • most_common_vals, most_common_freqs, histogram_bounds
    • most_common_elems, most_common_elem_freqs, elem_count_histogram
    • correlation

Statistiques : multi-colonnes

  • Pas par dĂ©faut
  • CREATE STATISTICS
  • Deux types de statistique
    • nombre de valeurs distinctes
    • dĂ©pendances fonctionnelles
  • Ă€ partir de la version 10

Catalogue pg_statistic_ext

  • Une ligne par objet statistique
  • 4 colonnes d'identification
    • stxrelid, stxname, stxnamespace, stxkeys
  • 1 colonne pour connaĂ®tre le type de statistiques gĂ©rĂ©
    • stxkind
  • 2 colonnes d'informations statistiques
    • stxndistinct
    • stxdependencies

ANALYZE

  • Ordre SQL de calcul de statistiques
    • ANALYZE [ VERBOSE ] [ table [ ( colonne [, ...] ) ] ]
  • Sans argument : base entière
  • Avec argument : la table complète ou certaines colonnes seulement
  • Prend un Ă©chantillon de chaque table
  • Et calcule des statistiques sur cet Ă©chantillon
  • Si table vide, conservation des anciennes statistiques

Fréquence d'analyse

  • DĂ©pend principalement de la frĂ©quence des requĂŞtes DML
  • Cron
    • Avec psql
    • Avec vacuumdb (option --analyze-only en 9.0)
  • Autovacuum fait du ANALYZE
    • Pas sur les tables temporaires
    • Pas assez rapidement dans certains cas

Échantillon statistique

  • Se configure dans postgresql.conf
    • default_statistics_target = 100
  • Configurable par colonne

    ALTER TABLE nom ALTER [ COLUMN ] colonne SET STATISTICS valeur;
  • Par dĂ©faut, rĂ©cupère 30000 lignes au hasard
    • 300 * default_statistics_target
  • Va conserver les 100 valeurs les plus frĂ©quentes avec leur frĂ©quence

Qu'est-ce qu'un plan d'exécution ?

  • Plan d'exĂ©cution
    • reprĂ©sente les diffĂ©rentes opĂ©rations pour rĂ©pondre Ă  la requĂŞte
    • sous forme arborescente
    • composĂ© des nĹ“uds d'exĂ©cution
    • plusieurs opĂ©rations simples mises bout Ă  bout

Nœud d'exécution

  • NĹ“ud
    • opĂ©ration simple : lectures, jointures, tris, etc.
    • unitĂ© de traitement
    • produit et consomme des donnĂ©es
  • EnchaĂ®nement des opĂ©rations
    • chaque nĹ“ud produit les donnĂ©es consommĂ©es par le nĹ“ud parent
    • nĹ“ud final retourne les donnĂ©es Ă  l'utilisateur

Lecture d'un plan

Lecture d'un plan d'exécution

Options de l'EXPLAIN

  • Des options supplĂ©mentaires
    • ANALYZE
    • BUFFERS
    • COSTS
    • TIMING
    • VERBOSE
    • SUMMARY
    • FORMAT
  • Donnant des informations supplĂ©mentaires très utiles

Détecter les problèmes

  • DiffĂ©rence importante entre l'estimation du nombre de lignes et la rĂ©alitĂ©
  • Boucles
    • appels très nombreux dans une boucle (nested loop)
    • opĂ©ration lente sur lesquels PostgreSQL boucle
  • Temps d'exĂ©cution consĂ©quent sur une opĂ©ration
  • OpĂ©rations utilisant beaucoup de blocs (option BUFFERS)

Statistiques et coûts

  • DĂ©termine Ă  partir des statistiques
    • cardinalitĂ© des prĂ©dicats
    • cardinalitĂ© des jointures
  • CoĂ»t d'accès dĂ©terminĂ© selon
    • des cardinalitĂ©s
    • volumĂ©trie des tables

Nœuds d'exécution les plus courants

  • Un plan est composĂ© de nĹ“uds
    • certains produisent des donnĂ©es
    • d'autres consomment des donnĂ©es et les retournent
    • le nĹ“ud final retourne les donnĂ©es Ă  l'utilisateur
    • chaque nĹ“ud consomme au fur et Ă  mesure les donnĂ©es produites par les nĹ“uds parents

Noeuds de type parcours

  • Seq Scan
  • Parallel Seq Scan
  • Function Scan
  • et des parcours d'index

Parcours d'index

  • Index Scan
  • Index Only Scan
  • Bitmap Index Scan
  • Et leurs versions parallĂ©lisĂ©es

Noeuds de jointure

  • PostgreSQL implĂ©mente les 3 algorithmes de jointures habituels :
    • Nested Loop (boucle imbriquĂ©e)
    • Hash Join (hachage de la table interne)
    • Merge Join (tri-fusion)
  • ParallĂ©lisation possible
    • version 9.6 pour Nested Loop et Hash Join
    • version 10 pour Merge Join
  • Et pour EXISTS, IN et certaines jointures externes :
    • Semi Join et Anti Join

PostgreSQL dispose de la parallélisation depuis la version 9.6. Cela ne concernait que les jointures de type Nested Loop et Hash Join. Quant au Merge Join, il a fallu attendre la version 10 pour que la parallélisation soit supportée.

Noeuds de tris et de regroupements

  • Un seul noeud de tri :
    • Sort
  • Regroupement/AgrĂ©gation :
    • Aggregate
    • HashAggregate
    • GroupAggregate
    • Partial Aggregate/Finalize Aggregate

Les autres noeuds

  • Limit
  • Unique
  • Append (UNION ALL), Except, Intersect
  • Gather
  • InitPlan, Subplan, etc.

Problèmes les plus courants

  • L'optimiseur se trompe parfois
    • mauvaises statistiques
    • Ă©criture particulière de la requĂŞte
    • problèmes connus de l'optimiseur

Colonnes corrélées

SELECT * FROM t1 WHERE c1=1 AND c2=1
  • c1=1 est vrai pour 20% des lignes
  • c2=1 est vrai pour 10% des lignes
  • Le planificateur va penser que le rĂ©sultat complet ne rĂ©cupĂ©rera que 20% * 10% (soit 2%) des lignes
    • En rĂ©alitĂ©, ça peut aller de 0 Ă  10% des lignes
  • Problème corrigĂ© en version 10
    • CREATE STATISTICS pour des statistiques multi-colonnes

Mauvaise écriture de prédicats

SELECT *
FROM commandes
WHERE extract('year' from date_commande) = 2014;
  • L'optimiseur n'a pas de statistiques sur le rĂ©sultat de la fonction extract
    • il estime la sĂ©lectivitĂ© du prĂ©dicat Ă  0.5%.

Problème avec LIKE

SELECT * FROM t1 WHERE c2 LIKE 'x%';
  • PostgreSQL peut utiliser un index dans ce cas
  • Si l'encodage n'est pas C, il faut dĂ©clarer l'index avec une classe d'opĂ©rateur
    • varchar_pattern_ops, text_pattern_ops, etc
  • En 9.1, il faut aussi faire attention au collationnement
  • Ne pas oublier pg_trgm (surtout en 9.1) et FTS

Problèmes avec LIMIT

  • Exemple
    • EXPLAIN avec LIMIT 199
    • EXPLAIN avec LIMIT 200
  • CorrigĂ© en 9.2

DELETE lent

  • DELETE lent
  • GĂ©nĂ©ralement un problème de clĂ© Ă©trangère
Delete  (actual time=111.251..111.251 rows=0 loops=1)
  ->  Hash Join  (actual time=1.094..21.402 rows=9347 loops=1)
        ->  Seq Scan on lot_a30_descr_lot
            (actual time=0.007..11.248 rows=34934 loops=1)
        ->  Hash  (actual time=0.501..0.501 rows=561 loops=1)
              ->  Bitmap Heap Scan on lot_a10_pdl
                  (actual time=0.121..0.326 rows=561 loops=1)
                    Recheck Cond: (id_fantoir_commune = 320013)
                    ->  Bitmap Index Scan on...
                        (actual time=0.101..0.101 rows=561 loops=1)
                          Index Cond: (id_fantoir_commune = 320013)
Trigger for constraint fk_lotlocal_lota30descrlot:
  time=1010.358 calls=9347
Trigger for constraint fk_nonbatia21descrsuf_lota30descrlot:
  time=2311695.025 calls=9347
Total runtime: 2312835.032 ms

DĂ©doublonnage

SELECT DISTINCT t1.* FROM t1 JOIN t2 ON (t1.id=t2.t1_id);
  • DISTINCT est souvent utilisĂ© pour dĂ©doublonner les lignes de t1
    • mais gĂ©nère un tri qui pĂ©nalise les performances
  • GROUP BY est plus rapide
  • Une clĂ© primaire permet de dĂ©doublonner efficacement des lignes
    • Ă  utiliser avec GROUP BY

Index inutilisés

  • Trop de lignes retournĂ©es
  • PrĂ©dicat incluant une transformation :

    WHERE col1 + 2 > 5
  • Statistiques pas Ă  jour ou peu prĂ©cises
  • OpĂ©rateur non-supportĂ© par l'index :

    WHERE col1 <> 'valeur';
  • ParamĂ©trage de PostgreSQL : effective_cache_size

Écriture du SQL

  • NOT IN avec une sous-requĂŞte
    • Ă  remplacer par NOT EXISTS
  • Utilisation systĂ©matique de UNION au lieu de UNION ALL
    • entraĂ®ne un tri systĂ©matique
  • Sous-requĂŞte dans le SELECT
    • utiliser LATERAL

Outils

  • pgAdmin3
  • explain.depesz.com
  • pev
  • auto_explain
  • plantuner

pgAdmin3

  • Vision graphique d'un EXPLAIN
  • Une icĂ´ne par nĹ“ud
  • La taille des flèches dĂ©pend de la quantitĂ© de donnĂ©es
  • Le dĂ©tail de chaque nĹ“ud est affichĂ© en survolant les nĹ“uds

pgAdmin3 - copie d'Ă©cran

EXPLAIN par pgAdmin

Site explain.depesz.com

  • Site web proposant un affichage particulier du EXPLAIN ANALYZE
  • Il ne travaille que sur les informations rĂ©elles
  • Les lignes sont colorĂ©es pour indiquer les problèmes
    • Blanc, tout va bien
    • Jaune, inquiĂ©tant
    • Marron, plus inquiĂ©tant
    • Rouge, très inquiĂ©tant
  • Installable en local

explain.depesz.com - copie d'Ă©cran

explain.depesz.com

Site pev

  • Site web proposant un affichage particulier du EXPLAIN ANALYZE
    • mais diffĂ©rent de celui de Depesz
  • Fournir un plan d'exĂ©cution en JSON
  • Installable en local

pev - copie d'Ă©cran

EXPLAIN par pev

Extension auto_explain

  • Extension pour PostgreSQL >= 8.4
  • ConnaĂ®tre les requĂŞtes lentes est bien
  • Mais difficile de connaĂ®tre leur plan d'exĂ©cution au moment oĂą elles ont Ă©tĂ© lentes
  • D'oĂą le module auto_explain

Extension plantuner

  • Extension, pour PostgreSQL >= 8.4
  • Suivant la configuration
    • Interdit l'utilisation de certains index
    • Force Ă  zĂ©ro les statistiques d'une table vide

Conclusion

  • Planificateur très avancĂ©
  • Mais faillible
  • Cependant
    • ne pensez pas ĂŞtre plus intelligent que le planificateur

Questions

N'hésitez pas, c'est le moment !

Annexe : NĹ“uds d'un plan

  • Quatre types de nĹ“uds
    • Parcours (de table, d'index, de TID, etc.)
    • Jointures (Nested Loop, Sort/Merge Join, Hash Join)
    • OpĂ©rateurs sur des ensembles (Append, Except, Intersect, etc.)
    • Et quelques autres (Sort, Aggregate, Unique, Limit, Materialize)

Parcours

  • Ne prend rien en entrĂ©e
  • Mais renvoie un ensemble de donnĂ©es
    • TriĂ© ou non, filtrĂ© ou non
  • Exemples typiques
    • Parcours sĂ©quentiel d'une table, avec ou sans filtrage des enregistrements produits
    • Parcours par un index, avec ou sans filtrage supplĂ©mentaire

Parcours de table

  • Parcours sĂ©quentiel de la table (Sequential Scan, ou SeqScan)
  • Aussi appelĂ© FULL TABLE SCAN par d'autres SGBD
  • La table est lue entièrement
    • MĂŞme si seulement quelques lignes satisfont la requĂŞte
    • Sauf dans le cas de la clause LIMIT sans ORDER BY
  • Elle est lue sĂ©quentiellement par bloc de 8 Ko
  • Optimisation synchronize_seqscans

Parcours d'index

  • Parcours alĂ©atoire de l'index
  • Pour chaque enregistrement correspondant Ă  la recherche
    • Parcours non sĂ©quentiel de la table (pour vĂ©rifier la visibilitĂ© de la ligne)
  • Sur d'autres SGBD, cela revient Ă  un
    • INDEX RANGE SCAN, suivi d'un TABLE ACCESS BY INDEX ROWID
  • Gros gain en performance quand le filtre est très sĂ©lectif
  • L'ensemble de lignes renvoyĂ© est triĂ©

Parcours d'index bitmap

  • En VO, Bitmap Index Scan / Bitmap Heap Scan
  • Disponible Ă  partir de la 8.1
  • Diminuer les dĂ©placements de la tĂŞte de lecture en dĂ©couplant le parcours de l'index du parcours de la table
    • Lecture en un bloc de l'index
    • Lecture en un bloc de la partie intĂ©ressante de la table
  • Autre intĂ©rĂŞt : pouvoir combiner plusieurs index en mĂ©moire
    • NĹ“ud BitmapAnd
    • NĹ“ud BitmapOr
  • CoĂ»t de dĂ©marrage gĂ©nĂ©ralement important
    • Parcours moins intĂ©ressant avec une clause LIMIT

Parcours d'index seul

  • Avant la 9.2, pour une requĂŞte de ce type
    • SELECT c1 FROM t1 WHERE c1<10
  • PostgreSQL devait lire l'index et la table
    • car les informations de visibilitĂ© ne se trouvent que dans la table
  • En 9.2, le planificateur peut utiliser la « Visibility Map »
    • nouveau nĹ“ud « Index Only Scan »
    • Index B-Tree (9.2+)
    • Index SP-GiST (9.2+)
    • Index GiST (9.5+) => Types : point, box, inet, range

Parcours : autres

  • TID Scan
  • Function Scan
  • Values
  • Result

Jointures

  • Prend deux ensembles de donnĂ©es en entrĂ©e
    • L'une est appelĂ©e inner (interne)
    • L'autre est appelĂ©e outer (externe)
  • Et renvoie un seul ensemble de donnĂ©es
  • Exemples typiques
    • Nested Loop, Merge Join, Hash Join

Nested Loop

  • Pour chaque ligne de la relation externe
    • Pour chaque ligne de la relation interne
    • Si la condition de jointure est avĂ©rĂ©e
      • Émettre la ligne en rĂ©sultat
  • L'ensemble externe n'est parcouru qu'une fois
  • L'ensemble interne est parcouru pour chaque ligne de l'ensemble externe
    • Avoir un index utilisable sur l'ensemble interne augmente fortement les performances

Merge Join

  • Trier l'ensemble interne
  • Trier l'ensemble externe
  • Tant qu'il reste des lignes dans un des ensembles
    • Lire les deux ensembles en parallèle
    • Lorsque la condition de jointure est avĂ©rĂ©e
    • Émettre la ligne en rĂ©sultat
  • Parcourir les deux ensembles triĂ©s (d'oĂą Sort-Merge Join)
  • Ne gère que les conditions avec Ă©galitĂ©
  • Produit un ensemble rĂ©sultat triĂ©
  • Le plus rapide sur de gros ensembles de donnĂ©es

Hash Join

  • Calculer le hachage de chaque ligne de l'ensemble interne
  • Tant qu'il reste des lignes dans l'ensemble externe
    • Hacher la ligne lue
    • Comparer ce hachage aux lignes hachĂ©es de l'ensemble interne
    • Si une correspondance est trouvĂ©e
    • Émettre la ligne trouvĂ©e en rĂ©sultat
  • Ne gère que les conditions avec Ă©galitĂ©
  • IdĂ©al pour joindre une grande table Ă  une petite table
  • CoĂ»t de dĂ©marrage important Ă  cause du hachage de la table

Suppression d'une jointure

SELECT pg_class.relname, pg_class.reltuples
FROM pg_class
LEFT JOIN pg_namespace
       ON pg_class.relnamespace=pg_namespace.oid;
  • Un index unique existe sur la colonne oid de pg_namespace
  • Jointure inutile
    • sa prĂ©sence ne change pas le rĂ©sultat
  • PostgreSQL peut supprimer la jointure Ă  partir de la 9.0

Ordre de jointure

  • Trouver le bon ordre de jointure est un point clĂ© dans la recherche de performances
  • Nombre de possibilitĂ©s en augmentation factorielle avec le nombre de tables
  • Si petit nombre, recherche exhaustive
  • Sinon, utilisation d'heuristiques et de GEQO
    • Limite le temps de planification et l'utilisation de mĂ©moire
    • GEQO remplacĂ© par Simulated Annealing ? (recuit simulĂ© en VF)

Opérations ensemblistes

  • Prend un ou plusieurs ensembles de donnĂ©es en entrĂ©e
  • Et renvoie un ensemble de donnĂ©es
  • Concernent principalement les requĂŞtes sur des tables partitionnĂ©es ou hĂ©ritĂ©es
  • Exemples typiques
    • Append
    • Intersect
    • Except

Append

  • Prend plusieurs ensembles de donnĂ©es
  • Fournit un ensemble de donnĂ©es en sortie
    • Non triĂ©
  • UtilisĂ© par les requĂŞtes
    • Sur des tables hĂ©ritĂ©es (partitionnement inclus)
    • Ayant des UNION ALL et des UNION
    • Attention que le UNION sans ALL Ă©limine les duplicats, ce qui nĂ©cessite une opĂ©ration supplĂ©mentaire de tri

MergeAppend

  • Append avec optimisation
  • Fournit un ensemble de donnĂ©es en sortie triĂ©
  • UtilisĂ© par les requĂŞtes
    • UNION ALL ou partitionnement/hĂ©ritage
    • Utilisant des parcours triĂ©s
    • IdĂ©al avec Limit

Autres

  • NĹ“ud HashSetOp Except
    • instructions EXCEPT et EXCEPT ALL
  • NĹ“ud HashSetOp Intersect
    • instructions INTERSECT et INTERSECT ALL

Divers

  • Prend un ensemble de donnĂ©es en entrĂ©e
  • Et renvoie un ensemble de donnĂ©es
  • Exemples typiques
    • Sort
    • Aggregate
    • Unique
    • Limit
    • InitPlan, SubPlan

Sort

  • UtilisĂ© pour le ORDER BY
    • Mais aussi DISTINCT, GROUP BY, UNION
    • Les jointures de type Merge Join
  • Gros dĂ©lai de dĂ©marrage
  • Trois types de tri
    • En mĂ©moire, tri quicksort
    • En mĂ©moire, tri top-N heapsort (si clause LIMIT)
    • Sur disque

Aggregate

  • AgrĂ©gat complet
  • Pour un seul rĂ©sultat

Hash Aggregate

  • Hachage de chaque n-uplet de regroupement (group by)
  • accès direct Ă  chaque n-uplet pour appliquer fonction d’agrĂ©gat
  • IntĂ©ressant si l'ensemble des valeurs distinctes tient en mĂ©moire, dangereux sinon

Group Aggregate

  • Reçoit des donnĂ©es dĂ©jĂ  triĂ©es
  • Parcours des donnĂ©es
    • Regroupement du groupe prĂ©cĂ©dent arrivĂ© Ă  une donnĂ©e diffĂ©rente

Unique

  • Reçoit des donnĂ©es dĂ©jĂ  triĂ©es
  • Parcours des donnĂ©es
    • Renvoi de la donnĂ©e prĂ©cĂ©dente une fois arrivĂ© Ă  une donnĂ©e diffĂ©rente
  • RĂ©sultat triĂ©

Limit

  • Permet de limiter le nombre de rĂ©sultats renvoyĂ©s
  • UtilisĂ© par
    • clauses LIMIT et OFFSET d'une requĂŞte SELECT
    • fonctions min() et max() quand il n'y a pas de clause WHERE et qu'il y a un index
  • Le nĹ“ud prĂ©cĂ©dent sera de prĂ©fĂ©rence un nĹ“ud dont le coĂ»t de dĂ©marrage est peu Ă©levĂ© (SeqScan, NestedLoop)

Travaux Pratiques