Welcome to Sign in | Help

Re: optimizare cross apply

  •  03-25-2011, 9:53 AM

    Re: optimizare cross apply

    O optimizare ar fii sa incerci pe cat posibil sa muti codul din cross apply in JOIN. Cum cross (dar si outer) apply se executa pt fiecare rand, pt ca foloseste in input coloane din interogarea principala, imi dau seama ca nu poti sa elimini definitiv acest operator insa ai putea, daca cerintele si resursele iti permit, sa executi calculele din operator pt tot setul de date si apoi sa faci join. O alta optimizare ar fii sa verifici codul din operator, sa te asiguri ca ruleaza foarte repede. Verifica indexarea tabelelor implicate in interogare. Asigurate ca nu folosesti outer apply daca nu se impune acest caz (este cam aceeasi deosebire ca in cazul INNER JOIN cu RIGHT JOIN). Totusi, cross apply se "misca"repede cand calculele sunt simple, deci nu intodeauna este de dorit sa-l inlocuiesti. In exemplul meu de mai jos am facut o interogare pe o baza de productie si pt fiecare tabela din baza de date, am adus numarul de coloane dupa care am sortat lista descendent dupa numarul de coloane. In primul exemplu am folosit outer apply pt exemplificare contra variantei cu INNER JOIN. Outer apply foloseste 66% din timpul total de executie, cu cross apply doar 47% (mai bine decat cu INNER JOIN, aici este interesant ca daca folosesc cross join in prima interogare si LEFT join in a 2-a, timpul devine 50 %, adica LEFT JOIN este mai rapid decat JOIN). Desigur, daca complici interogarea din apply, atunci si timpul va creste si vei observa ca nu mai este eficient acest operator, dar pt astfel de calcule este in regula. Un exemplu practic unde cross apply nu este eficient este solvabilitatea unui client sau sumele restante pentru clienti/furnizori unde pt un ID dat (client sau furnizor) trebuie sa faci agregari peste valori de documente cuprinse intr-o perioada sau nu, si sa afli sumele restante. In aceste cazuri, calculele nu sunt grele insa necesita resurse si prelucreaza un numar mare de randuri, este de preferat varianta cu JOIN (sa obtii lista tuturor clientilor/furnizorilor pt care ai de calculat, faci calculele si unesti aceste calcule cu restul interogarii prin JOIN).

    SELECT object_id, QUOTENAME(schema_name(schema_id)) + '.' + QUOTENAME(name) AS Tabela, c.CountOfColumns
    FROM sys.tables t
    outer apply (
    SELECT COUNT(*) AS CountOfColumns
    FROM sys.columns c1
    WHERE t.object_id = c1.object_id
    ) c
    ORDER BY CountOfColumns DESC

    SELECT QUOTENAME(schema_name(schema_id)) + '.' + QUOTENAME(name) AS Tabela, c.CountOfColumns
    FROM sys.tables t
    INNER JOIN (
    SELECT object_id, COUNT(*) AS CountOfColumns
    FROM sys.columns
    GROUP BY object_id
    ) c ON t.object_id = c.object_id
    ORDER BY CountOfColumns DESC
    Cătălin D.
View Complete Thread
Powered by Community Server (Commercial Edition), by Telligent Systems