Vous pouvez lire la trame de fond si vous le souhaitez, après avoir modifié mon index non cluster en un index clusterisé, les choses ont démarré beaucoup plus rapidement. Le problème avec le plan de requête initial prenant 2-3 secondes reste quand même. Cependant, l'indicateur de requête de plan de maintenance a été amélioré un peu.Mise en cache du plan de requête et performances
Backstory
J'ai un index inversé où je stocke des choses que je désire rechercher dans une implémentation simple de recherche (mais il n'y a rien de simple recherche).
Quand j'entre une requête comme celui-ci « ma br » il va créer cette SQL
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p0
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p1
[email protected] String --'ma%'
[email protected] String --'br%'
Pour chaque terme de recherche, il y a un autre INTERSECT
et SELECT
Et pour la plupart cela fonctionne très bien . J'ai indexé la colonne Term
correctement et vérifié les plans d'exécution pour les goulots d'étranglement potentiels. À l'heure actuelle, l'index contient environ 150 000 lignes et les recherches se font instantanément, comme prévu. Mais ce qui est un peu irritant, c'est que la première requête d'un certain rang prend beaucoup plus de temps à s'exécuter. Je parie que c'est parce que l'optimiseur de requête réévalue le plan d'exécution. Mais comment dois-je faire face à cela? Plus je lance de requêtes sur le serveur, moins il bloque, mais toutes les autres requêtes prennent environ 2-3 secondes de plus. Ce n'est pas un gros problème, mais parfois c'est beaucoup plus long et je ne vois pas d'où cela vient ni comment y faire face. Cela devrait être rapide comme l'éclair.
EDIT
schéma ressemble à ceci:
CREATE TABLE InvertedIndex (
Term varchar(255) NOT NULL,
Ordinal tinyint NOT NULL,
EntityType tinyint NOT NULL,
EntityID int NOT NULL
)
Les deux indices sont les suivants:
CREATE NONCLUSTERED INDEX IX_InvertedIndex ON InvertedIndex (Term)
INCLUDE (Ordinal, EntityType, EntityID)
CREATE NONCLUSTERED INDEX IX_InvertedIndex_Reverse ON InvertedIndex (EntityType, EntityID)
Cette substance reste, ce qui se passe, des besoins d'insertion et de suppression lorsque l'index (index inversé) Pour être mis à jour et, par conséquent, une reconstruction complète, cela affectera-t-il l'utilisation d'un PLAN D'INTERROGATION?
Voici un exemple de la requête complète c'est vraiment lent atm, 3-5 secondes et je ne peux pas comprendre pourquoi ... La clause ORDER BY
est destinée à donner des mots qui correspondent à une certaine position ordre de tri plus élevé (se produire d'abord dans le jeu de résultats), cependant, ceci est devenu exponentiellement plus lent pour chaque terme de recherche.
WITH Search AS (
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p0
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p1
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p2
)
SELECT p.PersonID
, p.FullName
, p.Email
, p.MobilePhone
, p.HomeAddress
, p.HomeCity
FROM Search AS s
INNER JOIN Person AS p ON p.PersonID = s.EntityID AND s.EntityType = @pPersonEntityType
ORDER BY (CASE WHEN @p3 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p0 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END) + (CASE WHEN @p4 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p1 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END) + (CASE WHEN @p5 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p2 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END)
@p0 String --'ma%'
@p1 String --'br%'
@p2 String --'mi%'
@p3 Int32 --1
@p4 Int32 --2
@p5 Int32 --3
Le point de la requête ci-dessus est de rechercher tous les termes dans le InvertedIndex
, puis, pour chaque terme de recherche il y a une Intersect, c'est le conjuction logique que je souhaite utiliser pour limiter la recherche. L'ordinal représente la position originale du mot quand il a été indexé. Chaque entrée dans InvertedIndex représente un tuple et si le terme de recherche correspond à un élément de ce n-uplet, il est considéré comme une meilleure correspondance. C'est pourquoi j'ai besoin de faire cet ordre génial avec des sous-requêtes. Mais c'est vraiment lent.
RÉPONSE
Si je change IX_InvertedIndex
à un index ordonné en clusters il améliore la vitesse de requête par un ordre de grandeur (je ne sais pas pourquoi si):
CREATE CLUSTERED INDEX IX_InvertedIndex ON InvertedIndex (Term)
ça dépend ... Qu'est-ce que la table défintion et wha t les index sont définis? –
Vous avez une clé primaire et un index cluster unique? – gbn
Non, je n'en ai pas besoin. Au moins, je pars du principe qu'il n'y a aucune raison d'ajouter cela ici. Je me trompe? –