Citat:
Ursprungligen postat av
lasternassumma
CTE eller UDF – Finns det rationella skäl att föredra det ena?
Även om trådstarten egentligen handlar om blandning av (user defined) functions och CTE så tycker jag att frågeställningen vad man ska välja är principiellt intressant.
Jag har inte hållit på med detta tillräckligt mycket för att ha en bestämd åsikt, men vore ändå tacksam för råd från (dig Proton eller någon annan som har hållit på mer än jag med detta) om hur man ska resonera.
Jag har fått rådet att undvika UDF-er till förmån för CTE om möjligt, men har använt UDF så lite så jag kan inte riktigt motivera det ena eller det andra. CTE, som är definierat sedan ANSI-99, finns t.ex. i Postgres sedan 7.8 (2007), i MSSQL i SQL Server f.o.m. 2008 R2, Oracle (sedan ca 2008) och i MySQL sedan 8 (ca 2016) kan väl anses som etablerat. Oracle (och några till) har tidigare haft "CONNECT" som liknar CTE men inte är lika.
Därutöver har vi stored procedures, tillsammans tre (eller möjligen fyra) olika metoder.
Lätt att läsa, snabbt och utrymmeseffektivt
Mina frågor:
– Kan man ge generella råd att försöka använda i första hand en metod?
– Kan man säga typfall då det ena eller det andra är att föredra?
– Kan man säga typfall då en viss teknik är överlägsen i effektivitet?
Jag har "snöat in" lite på CTE-er. Kan man göra det eller måste man ha UDF-er och stored procedures som alternativ?
Jag har googlat lite och får intrycket att olika leverantörer av databasmotorer ger lite olika budskap. Kanske är CTE-er lite för nytt för "gamla SQL-rävar"?
–
Jag hade nog i längsta möjliga mån försökt undvika UDFer och istället använt vyer och CTE där det är möjligt.
Den främsta förklaringen till det är att relationsdatabaser inte är bra på att hantera ett och ett objekt utan de vill ha mängder att jobba med, dessutom kommer inte sql server att använda index om man använder udfer, inte ens på de udfer som returnerar tabelldata, utan där kommer optimeraren att använda en table lookup.
Det är väl ok på mindre datamängder, men det kan få rejäla prestandakonsekvenser på större datamängder, detta ser man om man kollar på den execution plan sql server genererar, man kommer även upptäcka det med sql sever profiler.
Jag har varit med om fall där man från att ha använt en UDF för att ta fram en status övergått till att joina in en vy som gjorde samma sak kapat körtiden med minst 50% för just den frågan.
Anledningen var att SQL server tvingades för varje rad den hittade köra igenom funktionen och använda resultatet för att avgöra om raden skulle med eller ej. Inte speciellt effektivt.
Så, i de fall det verkligen inte går att använda vyer eller cte kan man ju ta till en UDF, men de är rätt få.
Stored procedures och CTEer är ju inte riktigt samma sak. CTE används ju för att ta fram data du kan joina in i en fråga, en SP packar ju ihop logik och ger dig ett resultat av exekveringen, en SP är det ju inte meningen att du ska joina in i någon fråga, utan den ska ju anropas nånstans ifrån och sedan ge dig ett resultat. Att det sedan kan vara en annan SP som anropar den är ju något annat.