J'utilise MS SQL et je dois exécuter plusieurs requêtes sur la même table selon différents critères. Au début, j'ai exécuté chaque requête sur la table d'origine, bien qu'elles partagent toutes un certain filtrage (c'est-à-dire la date, le statut). Cela a pris beaucoup de temps (environ 2 minutes).
Il y a des doublons dans les lignes de données et tous les index sont NON CLUSTERES. Je ne suis intéressé que par 4 colonnes pour mes critères et le résultat devrait afficher le nombre uniquement, pour toutes les requêtes.
colonnes nécessaires: TABLE
, FIELD
, AFTER
, DATE
et il y a un index sur chacun DATE
et TABLE
.
Après avoir créé une table temporaire avec uniquement les champs dont j'ai besoin, elle est descendue à 1:40 minutes, ce qui est toujours très mauvais.
CREATE TABLE #TEMP
(
TABLE VARCHAR(30) NULL,
FIELD VARCHAR(30) NULL,
AFTER VARCHAR(1000) NULL,
DATE DATETIME,
SORT_ID INT IDENTITY(1,1)
)
CREATE CLUSTERED INDEX IX_ADT ON #TEMP(SORT_ID)
INSERT INTO #TEMP (TABLE, FIELD, AFTER, DATE)
SELECT TABLE, FIELD, AFTER, DATE
FROM mytbl WITH (NOLOCK)
WHERE TABLE = 'OTB' AND
FIELD = 'STATUS'
Runnig this -> (216598 ligne (s) affectée)
Étant donné que toutes les requêtes ne dépendent pas de la plage de dates, je ne l'ai pas incluse dans la requête. Le problème est qu'il faut plus de 1 minute pour insérer uniquement . L'insertion ci-dessus a pris 1:19 minutes
Je veux exécuter quelque chose comme ça pour plusieurs requêtes:
SELECT COUNT(*) AS COUNT
FROM #TEMP
WHERE AFTER = 'R' AND
DATE >= '2014-01-01' AND
DATE <= '2015-01-01'
C'est un problème avec l'insert plus que celui de la sélection, mais le temp a beaucoup moins de lignes que le tableau d'origine, ce qui pourrait être mieux que de parcourir le tableau plusieurs fois.
Comment puis-je optimiser cela?
ÉDITER
J'ai supprimé l'ID de tri, je pensais que le problème venait principalement de la sélection et non de l'insertion. C'était une supposition.
Je ne peux pas créer un unique sur n'importe quel index car il n'y a pas de champ ou de lignes uniques.
J'utilise SQL Server 2012.
Informations sur la table : il s'agit d'un segment de mémoire dont l'utilisation de l'espace est la suivante:
name rows reserved data index_size unused
mytbl 24869658 9204568 KB 3017952 KB 5816232 KB 370384 KB
SELECT COUNT(*) AS COUNT FROM original_table WHERE AFTER = 'R' AND DATE >= '2014-01-01' AND DATE < '2015-01-01'
, pourquoi n'essayez-vous pas d'optimiser chacune (requête) séparément? N'êtes-vous pas autorisé à ajouter des index à la table?TABLE
etFIELD
de la#temp
table (toutes les lignes ontTABLE = 'OTB' AND FIELD = 'STATUS'
pour la table temporaire spécifique après tout.)CREATE TABLE
instruction). Le vote négatif était dû au fait que la question n'était pas claire.Réponses:
La question est principalement de savoir comment optimiser l'instruction select:
Suppression des projections redondantes et ajout du
dbo
schéma présumé :Sans index comme
([TABLE],[FIELD]) INCLUDE ([AFTER],[DATE])
SQL Server, deux options principales sont possibles:[TABLE] = 'OTB'
et[FIELD] = 'STATUS'
(à l'aide deIDX6
), puis effectuez une recherche de tas (RID) par ligne pour récupérer les colonnes[AFTER]
et[DATE]
.Que l'optimiseur choisisse une analyse de tas ou une recherche d'index avec la recherche RID dépend de la sélectivité estimée des prédicats
[TABLE] = 'OTB'
et[FIELD] = 'STATUS'
. Vérifiez si le nombre estimé de lignes de la recherche correspond à la réalité. Sinon, mettez à jour vos statistiques. Testez la requête avec un indice de table forçant l'utilisation de l'index, si cette condition est raisonnablement sélective . Si l'optimiseur choisit actuellement la recherche d'index, testez les performances avec un indiceINDEX(0)
ouFORCESCAN
pour analyser le tas.Au-delà de cela, vous pouvez chercher à améliorer un peu l'analyse du tas en supprimant une partie de l'espace inutilisé (370 Mo). Dans SQL Server 2008, cela peut être fait en reconstruisant le tas. L'espace inutilisé dans les segments résulte souvent de suppressions effectuées sans verrouillage de table (sans verrouillage de table, les pages vides ne sont pas désallouées d'un segment). Les tables qui subissent des suppressions fréquentes sont souvent mieux stockées en tant que table en cluster pour cette raison.
Les performances de l'analyse du segment de mémoire dépendent de la quantité de table stockée en mémoire, de la quantité qui doit être lue sur le disque, du niveau de remplissage des pages, de la vitesse du stockage persistant, que l'analyse soit liée aux E / S ou au processeur ( le parallélisme peut aider).
Si les performances sont toujours inacceptables après avoir étudié tout ce qui précède, essayez de plaider en faveur d'un nouvel index. S'il est disponible sur votre version de SQL Server, un index filtré possible pour la requête donnée serait:
Envisagez également la compression d'index, si elle est disponible et avantageuse. Sans un nouvel index, vous ne pouvez pas faire grand-chose pour améliorer les performances de la requête donnée.
la source
IDX6 nonclustered located on PRIMARY TABLE, FIELD
. Peut-être que cela changerait les choses que vous avez mentionnées?Je pense qu'il y a lieu de changer les index ici parce que:
Ce serait également un bon cas d'utilisation pour les index columnstore non-cluster introduits dans SQL Server 2012, c'est-à-dire résumer / agréger quelques colonnes sur une grande table avec de nombreuses colonnes.
Bien que ces index aient pour effet secondaire de rendre la table en lecture seule (à l'exception du changement de partition), ils peuvent transformer les performances des requêtes d'agrégation dans les bonnes conditions. L'aspect en lecture seule peut être géré, soit en déposant et en recréant les données d'index ou de commutateur de partition simple dans la table.
J'ai mis en place un banc d'essai simple pour imiter votre configuration et j'ai constaté une bonne amélioration des performances:
Mes résultats, 6 secondes contre 0,08 secondes:
En résumé, essayez de créer un dossier avec votre patron pour faire changer les index ou au moins créer une sorte de processus du jour au lendemain où ces enregistrements sont découpés dans une table / base de données de rapports en lecture seule où vous pouvez faire votre travail et ajouter l'indexation approprié à cette charge de travail.
la source