Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/05/2011, 10h22   #1
Invité régulier
 
Inscription : mai 2010
Messages : 37
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 37
Points : 5
Points : 5
Par défaut Rapidité requête avec where ou colonne additionnelle

Bonjour,

j'ai une db avec plusieurs millions de lignes avec une colonne nvarchar(max) vide ou remplie sur laquelle je dois faire des centaines de recherches en fulltext/jour.

J'aurai voulu savoir ce qui allait rendre les requêtes plus rapide :

- lancer directement ma requête sans me soucier d'un "where .. is not null"
- ajouter ce "where .. is not null"
- travailler avec une colonne additionelle en booléen qui spécifie si la colonne est vide ou non

Merci.
Marc_L est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2011, 13h43   #2
Membre chevronné
 
Inscription : juillet 2006
Messages : 1 194
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 1 194
Points : 746
Points : 746
Quels sont vos critères de recherche ?
Tout ceux-ci apparaissent dans la clause WHERE ou vous faites des filtres sur le résultat dans un second temps ?
Sergejack est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 08h46   #3
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Bonjour,

j'ai une db avec plusieurs millions de lignes avec une colonne nvarchar(max) vide ou remplie sur laquelle je dois faire des centaines de recherches en fulltext/jour.

J'aurai voulu savoir ce qui allait rendre les requêtes plus rapide :

- lancer directement ma requête sans me soucier d'un "where .. is not null"
- ajouter ce "where .. is not null"
- travailler avec une colonne additionelle en booléen qui spécifie si la colonne est vide ou non

Merci.
Ce qui va être important c'est le choix de votre clé de recherche(clé définie sur la table pour votre indexation FULLTEXT), l'idéal est un auto incrément.

la recherche FULLTEXT sur votre colonne NVARCHAR(MAX) (au passage le UNICODE est'il nécessaire dans votre cas? avez vous des caractères autres que latin?) sera t'elle votre seul prédicat?


Je ne pense pas que différentier les colonnes NULL sera bénéfique car vous nez requetez pas vraiment sur la colonne mais sur des données indexées par le FULLTEXT.
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 09h28   #4
Invité régulier
 
Inscription : mai 2010
Messages : 37
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 37
Points : 5
Points : 5
Bonjour, mes requêtes les plus chargées ressemblent à ceci :

Code :
1
2
3
4
UPDATE TABLE SET ... 
WHERE col4 = 1 
AND col3 IS NULL 
AND CONTAINS (col5,'"abcd" AND "efgh" AND NOT "ijkl" AND NOT "mnop"') AND CONTAINS (col6,'"qrst" AND "xyz" ')
Ma clé est sur une colonne id auto-incrémentée et la colonne NVARCHAR(MAX) se doit d'être en unicode sans quoi, je serai contraint de passer par un remplacement obligatoire de tous les caractères diacritiques ... ce qui pourrait, sans doute, alléger le process.

La question concernait donc ces 2 filtres fulltext (CONTAINS). Devrais-je d'abord tester si la col5 et col6 sont nulles ou cela se fait-il indirectement par SQL Server de toute façon avant de passer à la suite?

Aussi, est-ce que la place des clauses a-t-elle une influence ? Mettre les "where is not null" dans début de WHERE ?

Merci.
Marc_L est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 09h51   #5
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Aussi, est-ce que la place des clauses a-t-elle une influence ? Mettre les "where is not null" dans début de WHERE ?
Non aucune, SQL SERVER est basé sur le cout... en gros il décortique votre requète puis détermine la manière la plus rapide de donner un résultat en fonction de la charge de votre server etc.

Citation:
UPDATE table SET ... WHERE col4 = 1 AND col3 IS NULL AND CONTAINS (col5,'"abcd" AND "efgh" AND NOT "ijkl" AND NOT "mnop"') AND CONTAINS (col6,'"qrst" AND "xyz" ')

est-ce un exemple bidon?

Vous tester si col3 est NULL puis vous faites vos recherches FULLTEXT sur deux autres colonnes?


Ici vous devez clairement avoir un index sur col4 par exemple.
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 09h58   #6
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Code :
1
2
3
 
DECLARE @ASCII VARCHAR(MAX)='ËîôÖœžŸÅÄÆ'
 PRINT @ASCII

Quel caractères diacritiques ne pouvez vous pas gérer en NON UNICODE?
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 11h19   #7
Invité régulier
 
Inscription : mai 2010
Messages : 37
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 37
Points : 5
Points : 5
Citation:
Envoyé par iberserk Voir le message
est-ce un exemple bidon?
Vous tester si col3 est NULL puis vous faites vos recherches FULLTEXT sur deux autres colonnes?
Non, l'exemple est ok.

Le process démarre en fait sur un premier serveur avec SSIS qui flag déjà certaines colonnes en fonction de ...
Ensuite, le tout est injecté sur un autre serveur sql où sera lancé cette requête.

Citation:
Envoyé par iberserk Voir le message
Ici vous devez clairement avoir un index sur col4 par exemple.
Y a-il un nombre d'occurences minimum à ne pas prendre en compte pour que cela vaille la peine de créer cet index?
Exemple d'une colonne tinyint avec à peine 4 valeurs différentes.

Pour l'unicode, tu as raison, mais je devrai quand même vérifier car SSIS prend ici des données du monde entier (internet) en dehors de ce qui est éloigné à 100% des caractères latin (asiatique, russe, etc.)

merci iberserk.
Marc_L est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 11h36   #8
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
AND CONTAINS (col5,'"abcd" AND "efgh" AND NOT "ijkl" AND NOT "mnop"') AND CONTAINS (col6,'"qrst" AND "xyz" ')
Quand je vois cela.... a quoi sert le FULLTEXT ici?

Vous pourriez obtenir de bonnes performances avec une colonne calculée indexée qui ferait le calcul lors de l'ajout... vous n'auriez plus qu'a filtrer dessus.

Quant à votre colonne avec 4 valeurs distinctes... le mieux est de tester l’intérêt de votre index...

Peut-être pouvez vous penser à un partitionnement de table sur cette valeur?
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 11h55   #9
Invité régulier
 
Inscription : mai 2010
Messages : 37
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 37
Points : 5
Points : 5
Citation:
Envoyé par iberserk Voir le message
Quand je vois cela.... a quoi sert le FULLTEXT ici?
Par exemple, je dois retrouver le modèle d'une voiture parmi des milliers de références dans 2 colonnes dont une en varchar(max) ... utiliser du LIKE prendrait une éternité.

Citation:
Envoyé par iberserk Voir le message
Vous pourriez obtenir de bonnes performances avec une colonne calculée indexée qui ferait le calcul lors de l'ajout... vous n'auriez plus qu'a filtrer dessus.
Pourriez-vous m'en dire plus ? Sur quelles colonnes ?

Citation:
Envoyé par iberserk Voir le message
Peut-être pouvez vous penser à un partitionnement de table sur cette valeur?
J'y penserai pour la suite quand le tout sera déjà au point de façon "simple" :-)
Marc_L est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 15h17   #10
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Bonjour,

Citation:
Envoyé par Marc_L
Par exemple, je dois retrouver le modèle d'une voiture parmi des milliers de références dans 2 colonnes dont une en varchar(max) ... utiliser du LIKE prendrait une éternité.
Pas forcément si la recherche est à chaque fois sur un début de chaîne et que la colonne est indexée.

Citation:
Envoyé par Marc_L
Devrais-je d'abord tester si la col5 et col6 sont nulles ou cela se fait-il indirectement par SQL Server de toute façon avant de passer à la suite?

Aussi, est-ce que la place des clauses a-t-elle une influence ? Mettre les "where is not null" dans début de WHERE ?
Comme vous l'a succinctement décrit iberserk, SQL Server collecte des statistiques de distribution des valeurs dans les colonnes et pour les index.
Il fait cela par échantillonnage.

L'ordre des filtres de la clause WHERE dans une requête n'ayant pas de sous-requête importe peu.
Il peut influer parfois (mais rarement) en tentant de déplacer le filtre du WHERE dans le prédicat d'une équi-jointure (INNER JOIN).

Citation:
Envoyé par =Marc_L
Mettre les "where is not null" dans début de WHERE ?
Non. En revanche, si vous avez peu de lignes (comparé au nombre total de lignes de la table (sp_spaceused) qui ne sont pas à NULL pour la colonne, alors ajouter un index sur la colonne filtré pas IS NOT NULL peut être avantageux (disponible seulement sous SQL Server 2008)

Citation:
Envoyé par iberserk
Vous pourriez obtenir de bonnes performances avec une colonne calculée indexée qui ferait le calcul lors de l'ajout... vous n'auriez plus qu'a filtrer dessus.
Même question.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 15h20   #11
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Vous pourriez obtenir de bonnes performances avec une colonne calculée indexée qui ferait le calcul lors de l'ajout... vous n'auriez plus qu'a filtrer dessus.
Je pensais à tester l'ajout d'une colonne calculée qui ferait déjà le prédicat du WHERE...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 15h25   #12
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Ça peut marcher si le prédicat du CONTAINS est tout le temps le même ... je doute que ce soit le cas
Peut-être sur col4 ?

Sans la définition de la table et son utilisation, pas facile

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 15h31   #13
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Sans la définition de la table et son utilisation, pas facile
+1
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 16h24   #14
Invité régulier
 
Inscription : mai 2010
Messages : 37
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 37
Points : 5
Points : 5
Citation:
Envoyé par elsuket Voir le message
Sans la définition de la table et son utilisation, pas facile
Je sais bien mais cela serait trop compliqué voir chaotique de tout décortiqué ;-)

Citation:
utiliser du LIKE prendrait une éternité.
Citation:
Pas forcément si la recherche est à chaque fois sur un début de chaîne et que la colonne est indexée.
Oui mais dans le cas présent, les infos sont générallement au beau milieu d'un texte (contenu d'une page html)

Citation:
Envoyé par elsuket Voir le message
ajouter un index sur la colonne filtré pas IS NOT NULL peut être avantageux
Je ne connaissais pas ... effectivement, après quelques recherches, cela pourra grandement me servir

Ok, je pense avoir eu les réponses dont j'avais besoin pour continuer.
Merci beaucoup.
Marc_L est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 16h57   #15
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
http://blog.developpez.com/elsuket/p...-d-u/#more7945
Citation:
Je sais bien mais cela serait trop compliqué voir chaotique de tout décortiqué ;-)
Donnez simplement la structure de la table, et expliquer ce que vous cherchez à obtenir par votre requête.

Citation:
Oui mais dans le cas présent, les infos sont générallement au beau milieu d'un texte (contenu d'une page html)
Maintenant je comprend mieux la question d'iberserk (désolé d'être un peu long à la détente ) sur la colonne calculée : je pense que vous pouvez extraire les champs du document HTML au moment de l'insertion.
De cette façon vous devriez même pouvoir vous passer du stockage du document HTML.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2011, 19h38   #16
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
(désolé d'être un peu long à la détente )
Décalage horaire plus chaleur: pas bon ça

Citation:
Je ne connaissais pas ... effectivement, après quelques recherches, cela pourra grandement me servir
A partir de 2008, vous pouvez ajouter un filtre à vos index (ajoutez simplement WHERE ... à la fin de la création de votre index).

Les gains peuvent-être très intéressant en terme temps de réponse mais permet aussi de ne pas mettre à jour certains index sur les INSERT UPDATE...

Dans tous les cas n’hésitez pas à nous faire un retour sur les gains/solutions que vous avez adopté, le forum sert aussi à çà...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h03.


 
 
 
 
Partenaires

Hébergement Web