Welcome to Sign in | Help
in Search

optimizare cross apply

Last post 03-25-2011, 7:32 PM by crestinul. 4 replies.
Sort Posts: Previous Next
  •  03-24-2011, 4:57 PM 8661

    optimizare cross apply

    Observ ca interogarile in care folosesc cross applu dureaza foarte mult ,stiti vreun work around cum as putea optimiza asta?
    Multumesc
    Secolul XXI ori va fi religios ori nu va fi deloc
  •  03-25-2011, 9:53 AM 8663 in reply to 8661

    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.
  •  03-25-2011, 10:23 AM 8664 in reply to 8661

    Re: optimizare cross apply

    Trimite totusi un exemplu de query lent + structura tabelelor implicate.
  •  03-25-2011, 12:38 PM 8665 in reply to 8661

    Re: optimizare cross apply

    Ești sigur că problema este prezentă doar la CROSS APPLY ?

    Pentru a optimiza ceva trebuie să știm ce să optimizam. Cu alte cuvinte trebuie să determinăm cauza/cauzele. Cauza poate sa fie un index lipsă, un index incomplet (care nu contine toate campurile necesare în interogare) sau un plan de execuție non-optim sau ... altceva (memorie insuficienta ...).

    Uzual, trebuie verificat dacă în planul de execuție există următorii operatori:
    - Clustered Index Scan,
    - Index Scan,
    - Key Lookup / Bookmark lookup. În general, aceștia sunt "baieții răi".

    Printre motivele pentru care planul de execuție contine un operator CI/I Scan se pot enumera:
    - Nu există indecși -> creezi indecși.
    - Exista indecși dar aceștia nu conțin toate câmpurile necesare execuției interogarii -> incluzi câmpurile lipsă în indecși (fie ca și câmpuri indexate fie ca și câmpuri neindexate - INCLUDE).
    - Există indecși, aceștia includ toate câmpurile dar se face Scan și nu Seek -> WITH(FORCE SEEK) (daca este SQL2008).
    - Există indecși, aceștia includ toate câmpurile, dar nu sunt utilizați -> actualizezi
    statisticile sau/si WITH(INDEX=...)
    - Selectivitate redusă a condițiilor din WHERE/GROUP BY -> indecși filtrați (discutabil)
    - Selectivitate variabilă a condițiilor (uzual asta presupune o filtrare dupa o data calendaristica; inițial anumiți utilizatori pot apela interogarea cu parametrii care au o selectivitate scăzută - [Clustered] Index Scan DataComanda BETWEEN '2001-01-21 00:00:00' AND '2011-03-24 23:59:59'- iar alți utilizatori pot apela interogarea cu niște parametrii care au o selectivitate mare - DataComanda BETWEEN '2011-03-23 00:00:00' AND '2011-03-24 23:59:59') -> OPTION(RECOMPILE) soluție problematică dacă interogarea are un numar mare de execuții.
    - statistici neactualizate -> actulizezi statisticile
    - tabela contine un volum mic de date.

    Pentru a elimina operatorul Key lookup / Bookmark lookup trebuie să incluzi în index toate câmpurile care sunt necesare în interogare.

    Observație: soluțiile prezentate anterior nu sunt întotdeauna soluțiile optime. Trebuie avut în vedere chiar opțiunea rescrierii (parțiale sau totale) interogării.

    Pentru evaluarea unei soluții de optimizare poți să te raportezi în primul rând la volumul datelor citite (logical reads: SET STATISTICS IO ON) și mai puțin la timp (SET STATISTICS TIME ON). Timpul de execuție poate fi influențat negativ de execuția altor task-uri.

    Alte informații: http://www.sommarskog.se/query-plan-mysteries.html
  •  03-25-2011, 7:32 PM 8666 in reply to 8665

    Re: optimizare cross apply

    Multumesc mult tuturor!
    Secolul XXI ori va fi religios ori nu va fi deloc
View as RSS news feed in XML
Powered by Community Server (Commercial Edition), by Telligent Systems