Avatar billede krsk Nybegynder
27. marts 2003 - 10:27 Der er 16 kommentarer og
2 løsninger

View bedre performance?

Hej

Er der nogen der har nogle snedige forslag til at forbedre dette view

Flere indexes? Syntax?

Jeg left joiner fordi jeg skal sikre mig at ingen kollonner fra A mistes. Dog ikke Accesstabellen som skal begrænse A (brugerkontrol)

Alle tabeller pånår A er meget små -100 rows
Table A har følgende index's:
IDX_NC_KAT
IDX_NC_NIVNAVN1
IDX_NC_NIVNAVN2
Table A har 370.000 rows

CREATE VIEW dbo.VW_BALI_AFS_UGE_0
AS
SELECT    d.kategori,
        a.kat,
            a.ANTAL,
        a.PRIS_ENGANG,
        a.PRIS_LOEBENDE,
        a.NIV1NAVN,
        a.NIV2NAVN,
        a.NIV3NAVN,
        a.NIV4NAVN,
        a.CU_PRODUKT_TEKST,
        a.PRODUKT_NUMMER,
        a.PRODUKT_GRP,
        a.PRODUKT_ELEMENT,
        a.PRODUKT_FUNKTION,
        a.INTERN_EKSTERN_MARK,
        a.ENHED,
        a.KUNDESEGMENT_COLUMBUS_KIS,
        a.FORHANDLER,
        a.TJENESTE,
        a.SERVICE_PROVIDER_KODE,
        c.service_prov_name as service_provider_navn,
        a.INDTASTENDE_ORG,
        a.ORG_NIVEAU1,
        a.ORG_NIVEAU2,
        a.ORG_NIVEAU3,
        a.ORG_NIVEAU4,
        a.ORG_NIVEAU5,
        a.ORG_NIVEAU6,
        a.AFSAETNING_KODE,
        a.KUNDESAGS_KODE,
        a.TRANSKODE,
        a.SAERGRUPPE_MARK_NY,
        a.SAERGRUPPE_MARK_GL,
        a.ORDRE_DATO,
        a.PERIODE,
        a.FRA_XFELT_NY,
        a.FRA_XFELT_GL,
        a.TIL_XFELT_NY,
        a.TIL_XFELT_GL,

        A.forvalgs_kode_indland,
        A.forvalgs_kode_udland,

        forvalgs_navn_udland =
              CASE b.oper_prefix_code
                    WHEN a.forvalgs_kode_udland  THEN b.oper_name
            ELSE ''
        End,
        forvalgs_navn_indland =
              CASE b.oper_prefix_code
                    WHEN a.forvalgs_kode_indland THEN b.oper_name
            ELSE ''
        End
       
FROM        dbo.BALI_AFS_UGE_0 A
LEFT JOIN dbo.bali_r3502_ref_forvalg B ON (A.forvalgs_kode_indland = B.oper_prefix_code OR A.forvalgs_kode_udland = B.oper_prefix_code)
                        AND b.start_date <= (convert(varchar,getdate(),101))
                        AND
                        (
                            B.end_date > (convert(varchar,getdate(),101))
                            OR
                            B.end_date is null
                        )
LEFT JOIN dbo.bali_r3502_ref_serv_prod C ON A.service_provider_kode=C.source_system_code
LEFT JOIN dbo.bali_r3502_ref_kategori D ON A.kat=D.kat
WHERE    (UPPER(A.ENHED) IN
                          (SELECT    UPPER(authValue) AS enhed
                          FROM          dbo.RowAccessControl
                          WHERE      userId = DBO.getSuser_Sname()
        AND systemId = 'BALI'
        AND startDate <= getDate()
        AND (endDate > getdate() OR endDate IS NULL)))

/Kristian :-)

p.s. Da der kan være mange gode tiltag vil jeg formodentlig splitte pointene til de forskellige.
Avatar billede bjornicle Nybegynder
27. marts 2003 - 10:38 #1
B.end_date er vel af typen datetime, saa hvorfor laver du en convert ?
plus du kan prove at smide et index paa den kolonne

Jeg vil tro at dette kode:
(A.forvalgs_kode_indland = B.oper_prefix_code OR A.forvalgs_kode_udland = B.oper_prefix_code)
er noget der traekker taender ud, du bor ihvertfald prove at indexere dem
desuden kan jeg se at du konvertere til UPPER(), har du med vilje sat collation til case-sensitive, ellers er det ogsaa vaerdilost

Du bor kore en "Profiler" paa din query og saa hvad MSSQL foreslaar at du gør
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 10:55 #2
Prøv at ændre "from dbo.BALI_AFS_UGE_0 a"
til

from (select * from dbo.BALI_AFS_UGE_0
WHERE    (UPPER(ENHED) IN
                          (SELECT    UPPER(authValue) AS enhed
                          FROM          dbo.RowAccessControl
                          WHERE      userId = DBO.getSuser_Sname()
        AND systemId = 'BALI'
        AND startDate <= getDate()
        AND (endDate > getdate() OR endDate IS NULL)))) A


Ideen er, at den tabel med flest poster skal du have hentet et begrænset antal poster først.
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 10:55 #3
Du skal så ikke have Where-betingelses med for de felter, der ligger i A.
Avatar billede krsk Nybegynder
27. marts 2003 - 11:49 #4
benny.tordrup--> Det foreslår er at jeg skal flytte where betingelse op over LEFT join eller hvad?

Gider du at forklare dette: "Ideen er, at den tabel med flest poster skal du have hentet et begrænset antal poster først."

***bjornicle:
Profiler er det det samme som "Estimated Execution Plan" hvis ikke hvad er det så og hvor kører jeg det.
Avatar billede bjornicle Nybegynder
27. marts 2003 - 11:54 #5
I profiler laver du lidt tracking over det load du vil analysere, saa korer du din query nogle gange, saa smider du det load ind i "Index Tuning Wizard" som kigger din DB igennem i henhold til din query og foreslaar nogle optimeringer
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 12:21 #6
Måske lidt dårlig formulering.

dbo.bali_afs_uge_0 indeholder ifølge dit udsagn 37.000 poster. Mit forslag er at lave en subquery, hvor du henter de poster, der skal bruges fra tabellen.
Avatar billede krsk Nybegynder
27. marts 2003 - 12:39 #7
>>>benny.tordrup

Med fare for at jeg har misforstået dig mener jeg ikke at det gav noget :-( Faktisk kørte det 2 sec længere.

Sådan ser det ud nu:

FROM       
(
select * from dbo.BALI_AFS_UGE_0
WHERE    ENHED IN
                          (SELECT authValue AS enhed
                          FROM          dbo.RowAccessControl
                          WHERE      userId = DBO.getSuser_Sname()
        AND systemId = 'BALI'
        AND startDate <= getDate()
        AND (endDate > getdate() OR endDate IS NULL))
)  A
LEFT JOIN dbo.bali_r3502_ref_forvalg B ON (A.forvalgs_kode_indland = B.oper_prefix_code OR A.forvalgs_kode_udland = B.oper_prefix_code)
                        AND b.start_date <= (convert(varchar,getdate(),101))
                        AND
                        (
                            B.end_date > (convert(varchar,getdate(),101))
                            OR
                            B.end_date is null
                        )
LEFT JOIN dbo.bali_r3502_ref_serv_prod C ON A.service_provider_kode=C.source_system_code
LEFT JOIN dbo.bali_r3502_ref_kategori D ON A.kat=D.kat
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 13:13 #8
Så prøv at tilføje et index på A på feltet Enhed.

Hvor mange poster er der i dbo.RowAccessControl?
Avatar billede krsk Nybegynder
27. marts 2003 - 13:53 #9
Der er mindre end 100 rækker i dbo.RowAccessControl.

Jeg forsøgte at sætte index på enhed. Desværre er granulariteten meget lav på enhed så derfor havde det ingen effekt umiddelbart...

Iflg. executionplan benytter den indexet. Tiden bliver dog brugt i de andre left joins og ikke ved joinet på accessControl...(78% siger den)
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 13:56 #10
Prøv:

FROM       
(
select * from dbo.BALI_AFS_UGE_0
WHERE    ENHED IN
                          (SELECT authValue AS enhed
                          FROM          dbo.RowAccessControl
                          WHERE      userId = DBO.getSuser_Sname()
        AND systemId = 'BALI'
        AND GetDate() between StartDate and IsNull(EndDate, '99991231'))
)  A
LEFT JOIN dbo.bali_r3502_ref_forvalg B ON (A.forvalgs_kode_indland = B.oper_prefix_code OR A.forvalgs_kode_udland = B.oper_prefix_code)
                        AND b.start_date <= (convert(varchar,getdate(),101))
                        AND
                        (
                            B.end_date > (convert(varchar,getdate(),101))
                            OR
                            B.end_date is null
                        )
LEFT JOIN dbo.bali_r3502_ref_serv_prod C ON A.service_provider_kode=C.source_system_code
LEFT JOIN dbo.bali_r3502_ref_kategori D ON A.kat=D.kat


Hvad datatype er b.Start_Date og b.EndDate?
Avatar billede krsk Nybegynder
27. marts 2003 - 13:58 #11
jeg prøver :-)

de er smalldatetime.
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 14:02 #12
FROM       
(
select * from dbo.BALI_AFS_UGE_0
WHERE    ENHED IN
                          (SELECT authValue AS enhed
                          FROM          dbo.RowAccessControl
                          WHERE      userId = DBO.getSuser_Sname()
        AND systemId = 'BALI'
        AND GetDate() between StartDate and IsNull(EndDate, '99991231'))
)  A
LEFT JOIN dbo.bali_r3502_ref_forvalg B ON (A.forvalgs_kode_indland = B.oper_prefix_code OR A.forvalgs_kode_udland = B.oper_prefix_code)
                        AND GetDate() between b.start_date and IsNull(b.End_Date, '99991231'))
LEFT JOIN dbo.bali_r3502_ref_serv_prod C ON A.service_provider_kode=C.source_system_code
LEFT JOIN dbo.bali_r3502_ref_kategori D ON A.kat=D.kat


Så er der ingen grund til konvertering
Avatar billede krsk Nybegynder
27. marts 2003 - 14:18 #13
Det har umiddelbart givet 3 sec forbedring (fra 57-54)

Lidt har jo også ret :-)

BTW: '99991231' dutter ikke i ms sql, er der ikke noget med max. +50 år som default.

Det er stadig de nestede loop ved left joinene som tager tiden 78% :-(
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 14:19 #14
Det kan godt være, at '99991231' ikke dur mod smalldatetime, men mod datetime gør det.

Hvad med '39991231'?
Avatar billede bennytordrup Nybegynder
27. marts 2003 - 14:20 #15
Index på A.Forvalgs_kode_udland, A.Forvalgs_kode_indland, a.service_provider_kode?
Avatar billede krsk Nybegynder
27. marts 2003 - 14:25 #16
Jeg satte index på service_provider_kode - det gav ikke noget.

Jeg brugte bare '20151231'
Avatar billede Slettet bruger
27. marts 2003 - 17:08 #17
se ms white paper på optimering af views http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql2k/html/indexedviews1.asp

og se også denne tråd på google. (http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&frame=right&th=cff963f226fa7dbc&seekm=e%23muo9hCBHA.2020%40tkmsftngp07#link17
Man skal lige have styr på sine options når man bruger indexed views
Avatar billede krsk Nybegynder
28. marts 2003 - 10:39 #18
Jeg takker for hjælpen! Ikke helt hvad jeg havde håbet på, men jeg prøver at rode videre :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester