2010-12-13 48 views
0

une fois il y avait une vue avec beaucoup de jointures:Plus grande vue jamais! Comment puis-je réduire ce monstre ??

CREATE VIEW [dbo].[V_BIGGEST_VIEW_EVER] 
AS 
SELECT {many many columns} 
FROM (SELECT * FROM dbo.T_CUS_TSK_TASK WHERE is_deleted=0) T 
    INNER JOIN dbo.V_CUS_GRP_GROUP G ON (T.group_id = G.group_id) 
    INNER JOIN dbo.T_BKK_DISCOUNT_TYPE DT ON (DT.discount_type_id=T.discount_type_id) 
    INNER JOIN dbo.T_BKK_CURRENCY DC ON (T.debit_currency_id=DC.currency_id) 
    INNER JOIN dbo.T_BKK_CURRENCY PC ON (T.payback_currency_id=PC.currency_id) 
    INNER JOIN dbo.T_BKK_CURRENCY FC ON (T.final_debit_currency_id=FC.currency_id) 
    INNER JOIN dbo.T_GLOBAL_COUNTER D1C ON (D1C.company_id=T.company_id AND 
    D1C.counter_name='PROFORMA_INVOICE_COUNTER') 
    INNER JOIN dbo.T_GLOBAL_COUNTER D2C ON (D2C.company_id=T.company_id AND 
    D2C.counter_name='TAX_INVOICE_COUNTER') 
    INNER JOIN dbo.T_GLOBAL_COUNTER D3C ON (D3C.company_id=T.company_id AND 
    D3C.counter_name='INVOICE_RECEIPT_COUNTER') 
    INNER JOIN dbo.T_GLOBAL_COUNTER D4C ON (D4C.company_id=T.company_id AND 
    D4C.counter_name='DELIVERY_NOTE_COUNTER') 
    INNER JOIN dbo.T_GLOBAL_COUNTER D5C ON (D5C.company_id=T.company_id AND 
    D5C.counter_name='BILL_OF_LADING_COUNTER') 
    INNER JOIN dbo.T_GLOBAL_COUNTER D6C ON (D6C.company_id=T.company_id AND 
    D6C.counter_name='CREDIT_INVOICE_COUNTER') 
    LEFT JOIN dbo.V_SYS_BRANCH BR ON (T.branch_id = BR.branch_id) 
    LEFT JOIN dbo.T_CUS_TSK_TASKS_ARRAY AR ON (T.array_id = AR.array_id) 
    LEFT JOIN dbo.T_DRIVER D ON (T.driver_id = D.driver_id) 
    LEFT JOIN dbo.T_VEHICLE V ON (T.vehicle_id = V.vehicle_id) 
    LEFT JOIN dbo.T_STF_INVITER I ON (T.inviter_id = I.inviter_id) 
    LEFT JOIN dbo.T_STF_SUBCONTRACTOR SC1 ON (SC1.subcontractor_id = D.subcontractor_id) 
    LEFT JOIN dbo.T_STF_SUBCONTRACTOR SC2 ON (SC2.subcontractor_id = T.subcontractor_id) 
    LEFT JOIN dbo.T_CUS_TSK_TASK_STATUS S ON (S.task_status_id=T.task_status_id) 
    LEFT JOIN dbo.V_STF_SUB_LOCATION SL1 ON (SL1.sub_location_id=T.start_sub_location_id) 
    LEFT JOIN dbo.V_STF_SUB_LOCATION SL2 ON (SL2.sub_location_id=T.end_sub_location_id) 
    LEFT JOIN dbo.T_STF_CUSTOMER CU ON (CU.customer_id=T.customer_id) 
    LEFT JOIN dbo.T_STF_CUSTOMER_SPLITTING_CODE SP ON (SP.splitting_id=T.splitting_id) 
    LEFT JOIN dbo.V_CUS_TSK_CREDIT_FOR_TASK CR ON CR.task_id=T.task_id 
    LEFT JOIN dbo.T_BKK_PROFORMA_INVOICE D1 ON (T.proforma_invoice_id=D1.proforma_invoice_id) 
    LEFT JOIN dbo.T_BKK_TAX_INVOICE D2 ON (T.tax_invoice_id=D2.tax_invoice_id) 
    LEFT JOIN dbo.T_BKK_INVOICE_RECEIPT D3 ON (T.invoice_receipt_id=D3.invoice_receipt_id) 
    LEFT JOIN dbo.T_BKK_DELIVERY_NOTE D4 ON (T.delivery_note_id=D4.delivery_note_id) 
    LEFT JOIN dbo.T_BKK_BILL_OF_LADING D5 ON (T.bill_of_lading_id=D5.bill_of_lading_id) 
    LEFT JOIN dbo.V_CUS_TSK_CONTAINER CONTAINER1 ON (CONTAINER1.container_id=T.container1_id) 
    LEFT JOIN dbo.V_CUS_TSK_CONTAINER CONTAINER2 ON (CONTAINER2.container_id=T.container2_id) 
    LEFT JOIN dbo.V_STF_TRAILER TRAILER1 ON (TRAILER1.trailer_id=T.trailer1_id) 
    LEFT JOIN dbo.V_STF_TRAILER TRAILER2 ON (TRAILER2.trailer_id=T.trailer2_id) 
    LEFT JOIN dbo.T_STF_LUGGAGE_TYPE LUGGAGE_TYPE ON (LUGGAGE_TYPE.luggage_type_id=T.luggage_type_id) 

Un jour l'utilisateur a demandé à la vue d'une requête:

SELECT {many many columns} 
FROM V_BIGGEST_VIEW_EVER 
WHERE {column1}=1 AND 
     {column2}=2 AND 
     ....... 
     {and so and so} 
     ....... 
     {columnN}=N 

Et le plus grand point de vue jamais paresseux travaillé et travaillé et après 5 minutes (!!) et pas moins, il renvoie des résultats.

Ces tables avaient des clés primaires et des clés étrangères.

Comment réduire le temps d'exécution de la requête? Comment puis-je réduire cette vue?

J'ai cherché sur Google mais je n'ai pas pu trouver quelque chose qui m'a aidé.

+2

Est-ce que chaque requête a besoin des informations de toutes ces jointures? –

+0

Oh. Ma. Dieu. Je seconde la question de Marcelo, est-ce vraiment nécessaire? – slezica

+0

Troisième. C'est hideux - mettez-le hors de sa misère ... – SimonJ

Répondre

3

Considérons pour une minute que la requête représente un besoin métier valide.

Ce n'est pas parce que la vue est grande que cela devrait mal fonctionner. Les performances de la sélection à partir de cette vue sont principalement déterminées par la disposition des tables sous-jacentes. Même avec une vue que gauche joint plus de 20 tables de recherche SQL Server doit renvoyer le résultat en millisecondes, à condition que la table T_CUS_TSK_TASK est correctement indexée pour la requête effectuée.

Vous devez aborder cela comme toute autre optimisation de requête. Étudiez les principaux facteurs d'ES (SET STATISTICS IO ON), examinez le plan de requête, examinez les estimations de cardinalité, déterminez si les statistiques sont correctes, examinez les indices d'index manquants de la requête et examinez comment modifier le schéma de la table en conséquence. Votre point de départ devrait être ceci: Designing Indexes. Même un rapide coup d'oeil à votre schéma de tables (non fourni en post) devrait révéler si, disons, deleted n'est pas la clé d'index clusterisée la plus à gauche, alors vous avez certainement un problème.

Votre approche actuelle de piratage aveugle à la requête en fonction de son texte est complètement non professionnel.

Maintenant, bien sûr, est dur pour croire que cette requête représente une exigence métier valide. Mais, néanmoins, votre point de vue sur l'optimisation des requêtes et la conception de modèles de données («Ces tables ont des clés primaires et des clés étrangères») est primitif, pour utiliser un terme doux. Lisez à propos de la conception de l'index, lisez à propos de la couverture des indices, achetez un livre (comme ceci: Inside Microsoft SQL Server 2005: Query Tuning and Optimization).