IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

ORDER BY et plan d'exécution


Sujet :

Développement SQL Server

  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut ORDER BY et plan d'exécution
    Bonjour,

    Je suis en train de suivre une formation (pas dédiée SQL) et le formateur nous dit que SQL Server (toutes versions) est pénalisé dans sa recherche du meilleur plan d'exécution par le contenu de la clause ORDER BY.

    Dans le cadre d'une requête monotable.

    1/ Il ne faut pas mixer les ASC et DESC sous peine d'avoir l'optimiseur qui ne prenne pas forcément le meilleur index
    2/ Dans tous les cas, il faut toujours ajouter en dernier la clé primaire de la table en ASC ou DESC en fonction de l'indicateur de tri choisi pour les autres colonnes.

    De prime abord, j'ai l'impression que c'est du total n'importe quoi.
    Pourtant le gars à priori il s'y connaît bien, plan d'exécution à l'appui.

    C'est vrai ça ?

    Note: quoique le truc est biaisé, l'outil ajoute systématiquement la clé primaire à la fin du ORDER BY en ASC sauf s'il est explicitement déjà déclaré en DESC. J'ai l'impression que c'est cet ajout qui fout le bordel. Des explications ?

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 995
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 995
    Billets dans le blog
    6
    Par défaut
    De toutes façons, un ORDER BY n'utilisera un index que si l'index est suffisamment couvrant pour tous les éléments de la requête. Dans le cas contraire, un tri sera effectué. Or SQL Server fonctionnant nativement de manière parallèle il battra la plupart des autres SGBDR en terme de temps d'exécution.
    Oracle nécessite un module externe payant qui s'appelle parallele query, tandis que PostGreSQL ne sait pas faire du parallélisme (pas de threading) sauf pour quelques rares cas et sur 4 opérateurs seulement et il faut lui indiquer comment faire.... Quant à MariaDB et MySQmerde... pas de parallélisme du tout....
    https://www.postgresql.org/message-i...163f4%40iki.fi
    https://postgresql.developpez.com/ac...t-il-la-peine/


    Donc je rigole par ce que comparer deux plans de requêtes de deux SGBDR différents, c'est comme comparer un moteur de voiture et celui d'un hors bord...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Euh, j'ai pas parlé d'Oracle (ou alors c'est une faute de frappe).

    On est bien en full SQL Server

  4. #4
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    En fait, il dit qu'avec la table suivante (simplifié) :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    create table personne
    (
    id int not null identity primary key,
    nom char(20) not null,
    prenom char(20) not null,
    age int not null default 0
    )
    go
     
    create index ix_nom on personne (nom, prenom)
    go

    Si on écrit ces requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from personne
    order by nom desc, prenom desc, id asc

    C'est plus lent que :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from personne
    order by nom desc, prenom desc, id desc

    Et que :
    C'est plus lent que :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from personne
    order by nom desc, prenom asc, id asc

    Normal ?

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 995
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 995
    Billets dans le blog
    6
    Par défaut
    NON.... Pour preuve :

    -- la table de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE SCHEMA S_PRS;
    GO
     
    CREATE TABLE S_PRS.T_PERSONNE_PHYSIQUE_PSP
    (
    	"PRS_ID"              INT NOT NULL PRIMARY KEY,
    	"CVT_ID"              INT,
    	"PSP_NOM"             CHAR(32),
    	"PSP_PRENOM"          VARCHAR(25),
    	"PSP_DATE_NAISSANCE"  DATETIME2(0), --> mettre TIMESTAMP pour PostGreSQL
    	"PSP_SOUNDEX"         CHAR(4)
    )
    La table contient 1 253 609 lignes

    -- le script de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SET STATISTICS TIME ON
     
    select *
    from   S_PRS.T_PERSONNE_PHYSIQUE_PSP
    order  by PSP_NOM desc, PSP_PRENOM desc, PRS_ID asc;
    GO 10
     
    select *
    from   S_PRS.T_PERSONNE_PHYSIQUE_PSP
    order  by PSP_NOM desc, PSP_PRENOM desc, PRS_ID desc;
    GO 10
     
    select *
    from    S_PRS.T_PERSONNE_PHYSIQUE_PSP
    order  by PSP_NOM desc, PSP_PRENOM asc, PRS_ID asc;
    GO 10
    CREATE INDEX X1 ON S_PRS.T_PERSONNE_PHYSIQUE_PSP (PSP_NOM, PSP_PRENOM)

    Plan d'exécution des requêtes :
    Nom : SQL Server performances ORDER BY - 00.jpg
Affichages : 87
Taille : 459,0 Ko

    Les 3 plans sont identiques car cet index n'est pris par aucune requête puisqu'il n'est pas couvrant...

    -- synthèse des résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4250*ms, temps écoulé = 1803*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4356*ms, temps écoulé = 1886*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4265*ms, temps écoulé = 1433*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 3843*ms, temps écoulé = 1416*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 3984*ms, temps écoulé = 1425*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4065*ms, temps écoulé = 1435*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4203*ms, temps écoulé = 1378*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4140*ms, temps écoulé = 1432*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4062*ms, temps écoulé = 1317*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4189*ms, temps écoulé = 1422*ms.
    Exécution du lot effectuée*10*fois.
    ==> moyenne temps UC 4135.7
     
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4232*ms, temps écoulé = 1851*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4158*ms, temps écoulé = 1946*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4187*ms, temps écoulé = 1378*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4156*ms, temps écoulé = 1432*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4547*ms, temps écoulé = 1427*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4186*ms, temps écoulé = 1422*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4189*ms, temps écoulé = 1392*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 3985*ms, temps écoulé = 1424*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 3923*ms, temps écoulé = 1444*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4313*ms, temps écoulé = 1366*ms.
    Exécution du lot effectuée*10*fois.
    ==> moyenne temps UC 4187.6
     
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4263*ms, temps écoulé = 2002*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4032*ms, temps écoulé = 1872*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4013*ms, temps écoulé = 1425*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4173*ms, temps écoulé = 1301*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 3984*ms, temps écoulé = 1417*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4204*ms, temps écoulé = 1379*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4127*ms, temps écoulé = 1422*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4188*ms, temps écoulé = 1422*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4266*ms, temps écoulé = 1415*ms.
    (1253609*lignes affectées)
     SQL Server Temps d'exécution*: Temps UC = 4032*ms, temps écoulé = 1417*ms.
    Exécution du lot effectuée*10*fois.
    ==> moyenne temps UC 4128.2
    Bref,
    • requête 1, moyenne 4135.7
    • requête 2, moyenne 4187.6
    • requête 3, moyenne 4128.2


    Écart type : 32,34 ms (soit moins de 1%...)

    De toute façon c'est bidon car le SELECT * ne prendra jamais l'index !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Réponses: 11
    Dernier message: 28/04/2008, 16h29
  2. Plan d'exécution pas logique
    Par pat29 dans le forum Administration
    Réponses: 6
    Dernier message: 07/03/2008, 14h37
  3. Réponses: 12
    Dernier message: 22/06/2006, 10h26
  4. Plan d' exécution
    Par rod59 dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 15/06/2006, 21h50
  5. Comparer des plan d'exécution
    Par sygale dans le forum Oracle
    Réponses: 7
    Dernier message: 06/04/2006, 17h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo