2013-06-26 1 views
0

J'utilise une requête les colonnes de jointure l'un a un index cluster et l'autre a un index non-cluster. La requête prend beaucoup de temps. Est-ce la raison pour laquelle j'utilise différents types d'index?Joindre sur des colonnes avec des index différents

SELECT @NoOfOldBills = COUNT(*) 
FROM Billing_Detail D, Meter_Info m, Meter_Reading mr 
WHERE D.Meter_Reading_ID = mr.id 
    AND m.id = mr.Meter_Info_ID 
    AND m.id = @Meter_Info_ID 
    AND BillType = 'Meter' 

IF (@NoOfOldBills > 0) BEGIN 

    SELECT TOP 1 @PReadingDate = Bill_Date 
    FROM Billing_Detail D, Meter_Info m, Meter_Reading mr 
    WHERE D.Meter_Reading_ID = mr.id 
      AND m.id = mr.Meter_Info_ID 
      AND m.id = @Meter_Info_ID 
      AND billtype = 'Meter' 
    ORDER BY Bill_Date DESC 

END 
+4

Combien de lignes avez-vous dans la table? Combien d'index? Que dit le plan d'exécution? Où est votre code SQL? –

+0

150 k dans les deux tableaux. effectivement la requête est trop grande, mais le plan d'exécution dit que cette requête prend 33% et une requête similaire à cela prend également 33%, si je reçois une solution pour cela, je peux améliorer le temps. – Mustafa

+0

selection @NoOfOldBills = count (*) \t \t \t \t \t \t \t de Billing_Detail d, Meter_Info m, Meter_Reading mr \t \t \t \t \t \t \t où d.Meter_Reading_ID = mr.ID et m.Id = mr.Meter_Info_ID et M.Id = @ Meter_Info_ID ET BillType = 'Compteur' \t \t \t \t \t \t \t \t \t \t IF (@NoOfOldBills> 0) \t \t \t \t \t \t BEGIN \t \t \t \t \t \t \t \t \t sélectionner top 1 @ PReadingDate = Bill_Date \t \t \t \t \t \t \t \t de Billing_Detail d, Meter_Info m, Meter_Reading mr \t \t \t \t \t \t \t \t où d.Meter_Reading_ID = mr.ID et m.Id = mr.Meter_Info_ID et [email protected]_Info_ID et billtype = ordre 'mètre' par Bill_Date desc \t \t \t \t \t \t \t FIN – Mustafa

Répondre

0

OK, il y a un certain nombre de choses ici. Tout d'abord, les indices que vous avez pertinents (ou aussi pertinents qu'ils peuvent l'être). Il devrait y avoir un index clusterisé sur chaque table - un index non clusterisé ne fonctionne pas efficacement si la table n'a pas d'index clusterisé que les index non clusterisés utilisent pour identifier les lignes.

Votre index couvre-t-il une seule colonne? SQL Server utilise des index avec l'ordre des colonnes pour cet index étant très important. La colonne la plus à gauche de l'index doit (en général) être la colonne qui a l'ordinalité la plus grande (divise les données en les plus petites quantités) L'un ou l'autre des index couvre toutes les colonnes référencées dans la requête. index (Google pour plus d'informations)

En général, les index doivent être larges, si SQL Server a un index sur col1, col2, col3, col4 et un autre sur col1, col2 le dernier est redondant, comme l'information de la SQL Server peut/va choisir un plan d'exécution incorrect si les statistiques ne sont pas à jour. exécution du plan (requête SSMS | plan d'exécution show)?

+0

Chaque clé primaire dans les tables db a un index de cluster, et la clé étrangère a un index de non cluster. Et j'avais fait index sur une seule colonne, devrais-je couvrir toutes les colonnes? – Mustafa

+0

Oui, ajoutez un index de couverture ou bien autant d'index de couverture que nécessaire pour vous assurer que chaque moitié de chaque jointure est couverte. En fait, SSMS vous recommandera les index dont vous avez besoin lorsque vous analyserez la requête, cela était très floconneux dans le passé, mais s'est amélioré dans les versions récentes. Mais utilisez ses conseils judicieusement. –

1

Sans connaître plus de détails et le contexte, il est difficile à conseiller - mais il semble que vous essayez de trouver la date de la facture la plus ancienne. Vous pourriez probablement réécrire ces deux requêtes en une seule, ce qui améliorerait les performances de manière significative (en supposant qu'il existe d'anciennes factures).

Je suggérerais quelque chose comme ceci - qui, en plus de produire probablement mieux, est un peu plus facile à lire!

SELECT count(d.*) NoOfOldBills, MAX(d.Billing_Date) OldestBillingDate FROM Billing_Detail d 
    INNER JOIN Meter_Reading mr ON mr.id=d.Meter_Reading_ID 
    INNER JOIN Meter_Info m ON m.Id=mr.Meter_Info_ID 
WHERE 
    m.id = @Meter_Info_ID AND billtype = 'Meter' 
0

La raison n'est pas parce que vous avez différents types d'indices. Puisque vous avez dit que vous avez des index groupés sur toutes les clés primaires, vous devriez être bien là. Pour prendre en charge cette requête, vous avez également besoin d'un index avec deux colonnes sur BillType et Bill_Date pour réduire le temps.

Espérons qu'ils sont dans la même table. Sinon, vous aurez peut-être besoin de quelques index pour en créer un qui aura deux colonnes.

Questions connexes