Question

Je me joins à une douzaine de tables de différentes époques, et chaque fois, je me joins (ou filtre) sur la base des résultats d'une sous-chaîne de l'une des colonnes (c'est une chaîne, mais à gauche rembourré avec des zéros, et Je ne me soucie pas des quatre derniers chiffres). En conséquence, même si cette colonne est indexée et ma requête utiliserait l'index, il fait une analyse de la table, car la sous-chaîne elle-même est pas indexé, donc SQL Server doit calculer pour chaque ligne avant que cela se joindre.

Je cherche des idées sur la façon d'accélérer ce processus. À l'heure actuelle, il y a une vue sur la table (Il est un « SELECT * FROM », juste pour donner la table un nom convivial), et j'envisage d'ajouter une colonne à la vue qui est calculé, puis l'indexation qui. Je suis ouvert à d'autres suggestions, cependant - les pensées

?

Plus DETAIL: J'aurais partagé cela pour commencer. Le tableau reçoit la réplication de notre système de facturation, l'édition de sorte que la table sous-jacente pour ajouter une colonne calculée n'est pas une option. Toute colonne calculée devrait être ajoutée à la vue sur la table. En outre, les zéros conduisent pas toujours des zéros -. Ils sont parfois d'autres données que je ne suis pas intéressé, je suppose que la vraie question est « Comment puis-je me joindre aux données au milieu d'un moment de la colonne VARCHAR également faire usage d'un indice? Recherche en texte intégral? "

Clarifier mon exemple Je simplifie, mais essentiellement, disons que je suis en train de rechercher des valeurs dans une colonne avec les valeurs suivantes:

00000012345MoreStuff
00000012345Whatever
19834212345
Houses12345837443GGD
00000023456MoreStuff

Je suis intéressé par les lignes où SUBSTRING (7,5) = « 12345 », donc je veux les lignes 1-4, mais pas sur la ligne 5. Ce que je propose est d'ajouter une colonne à mon « SELECT * "vue qui a cette sous-chaîne, puis indexation basée sur ce point. Est-ce que plus de sens?

Était-ce utile?

La solution

En supposant que vous avez vos champs dans ce format:

00Data0007
000000Data0011
0000Data0015

, vous pouvez faire ce qui suit:

  • Créer une colonne calculée: ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    Ceci transformera vos colonnes en ce qui suit:

    ataD00
    ataD000000
    ataD0000
    
  • Créer un index sur cette colonne

  • Problème de cette requête pour rechercher la chaîne Data:

    SELECT  *
    FROM    mytable
    WHERE   ndata LIKE N'ataD%'
            AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD'))
    

    La première condition va utiliser un index pour le filtrage grossier.

    Le second fera en sorte que tous les personnages principaux (qui sont devenus les caractères de fin dans la colonne calculée) ne sont que des zéros.

Voir cette entrée dans mon blog pour les détails de la performance:

Mise à jour

Si vous voulez juste un index sur SUBSTRING sans changer votre schéma, la création d'un point de vue est une option.

CREATE VIEW v_substring75
WITH SCHEMABINDING
AS
SELECT  s.id, s.data, SUBSTRING(data, 7, 5) AS substring75
FROM    mytable

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id)

SELECT  id, data
FROM    v_substring75
WHERE   substring75 = '12345'

Autres conseils

Ajouter un colonne calculée à votre table et créer un index sur cette colonne.

ALTER TABLE MyTable
Add Column CodeHead As LEFT(Code,Len(Code)-4)

Ensuite, créez un index sur ce sujet.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead

Pouvez-vous reformuler vos critères de filtrage en termes d'une déclaration comme «quelque chose%? (Ceci est applicable à un indice)

Modifier la colonne à deux colonnes - les données et les rejoindre sur 4 caractères supplémentaires. L'utilisation de pièces d'une colonne ralentit les choses que vous HVE vu

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top