Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Seg user-defined scalar function.

Postades av 2007-06-13 16:04:24 - Fredrik Malmström, i forum sql-server/msde, Tråden har 24 Kommentarer och lästs av 1130 personer

Jag blir lite irriterad, har skapat en sql-sats som returnerar värden på under 1 sek om man tittar i SQL Server Management Studio när man testar satsen själv, samt som en subquery i andra sql-satser.

Nu vill jag implementera denna sql-sats i en user-defined scalar function, att skriva själva funktionen är inte problemet och få resultatet. 1 - 2 tester så var den "hyfsat snabb" under 3 sek när man använde sig av den i andra sql-satser sen.

Men sen efter de 1-2 testen, då blev den enormt seg. När jag hade den i sql-satserna hade den inte exekverat färdigt efter ens 1 minut, använde jag print, för bara funktionen då gick den lös på ca 20 sek.

Vad tror ni kan vara boven i dramat?


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-13 17:00:23 - Thomas Vanhaniemi

Vad är det egentligen för SQL frågor du har som tar så länge som 1 sekund och uppåt att exekvera? Vanligtvis brukar ju tiderna ligga kring någon millisekund. Är du säker på att du har index på rätt fält i databasen och att din SQL fråga är optimal?


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-13 17:04:56 - Fredrik Malmström

Så här ser i alla fall själva functionen ut från modify-läge:
<code>
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go




-- =============================================
-- Author: Fredrik Malmström
-- Create date: 20070613
-- Description: Beräknar antalet annonser under en viss period som underlag för fakturering
-- =============================================
ALTER FUNCTION [dbo].[ufn_CountAds]
(
-- Add the parameters for the function here
@CustomerID int, @StartDate datetime, @Stopdate datetime
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @Result int

-- SQL-sats för att returnera antalet annonser för import kunder som
-- skall vara underlag för fakturering

select @Result = (select sum(c.annonser) from (
select
(
select count(distinct custompropertyid) from properties where
imported between @StartDate and @StopDate and
customer=a.Customer
) As annonser
from properties a
inner join
customers b on
a.Customer=b.customerid
where a.customer=@CustomerID
-- end
UNION
-- SQL-sats beräkna antal annonser för ej importerad kund som skall
-- vara underlag för fakturering.
select
(
(
select count(*) from properties where customer=a.Customer
and deleted is null and imported is null
)
+
( select count(*) from properties where
deleted between @StartDate and @StopDate
and imported is null and
customer=a.Customer
)
) As annonser
from properties a
inner join
customers b on
a.Customer=b.customerid
where a.Customer=@CustomerID
) as c)

-- Returnera antalet annonser under den angivna perioden.
RETURN @Result

END</code>

Bara sql-satsen<code>
select sum(c.annonser) from (
select
(
select count(distinct custompropertyid) from properties where
imported between @StartDate and @StopDate and
customer=a.Customer
) As annonser
from properties a
inner join
customers b on
a.Customer=b.customerid
where a.customer=@CustomerID
-- end
UNION
-- SQL-sats beräkna antal annonser för ej importerad kund som skall
-- vara underlag för fakturering.
select
(
(
select count(*) from properties where customer=a.Customer
and deleted is null and imported is null
)
+
( select count(*) from properties where
deleted between @StartDate and @StopDate
and imported is null and
customer=a.Customer
)
) As annonser
from properties a
inner join
customers b on
a.Customer=b.customerid
where a.Customer=@CustomerID
) as c
</code>

Jag kan inte svara på vad som inte är riktigt optimalt, men den drar iväg mycket snabbare inom select-satser än som funktion


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-13 17:12:31 - Thomas Vanhaniemi

Oj vilka SQL satser du har. För det första brukar det i många fall ta mycket kraft ur servern att köra felaktiga SELECT satser inne i andra SELECT satser.
Om du beskriver hur de väsentligaste tabellerna ser ut och hur du vill ha ut data, gärna med små exempel, kan du nog få hjälp att optimera det hela till en enklare SQL sats som också är snabbare...

Jag är nu ingen expert på SQL server men SQL kan jag nog rätt bra...


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-13 18:03:34 - Fredrik Malmström

Tar bar upp de väsentliga kolumnerna som berörs.

Tabellen:Properties
propertyid | | customer | custompropertyid | created | deleted | updated | imported

Tabellen:Customers
customerid | Name | deleted


Properties innehåller annonser som är direkt skapade av någon kund, men även innehåller den importerade annonser från någon kund.

Det jag vill ha fram är antalet annonser som funnits under en viss period för båda två, dock importeras annonser varje dygn från de kunder som är importkunder, om en importerad annons med ex. custompropertyid 100 och tillhör en kund med customer=45 så skapas en ny post med tillhörande information, samt sätts created till begynnelsepostens created med samma custompropertyid och customer, deleted sätts till null, den tidigare begynnelsepostens deleted sätts til den nya postens import datum.

Därav har varje importerad annons flera upplagor av sig själv, så länge som den finns kvar hos exportören så växer antalet lika annonser.

Där av den första sql-satsen i union satsen skall räkna antalet distincta annonser (deleted som ej deleted) under en viss period, den andra räknar annonserna för de ej importerade under samma period med samma krav (deleted som inte deleted).

För perioden kan ha kanske 10 aktiva annonser, men det har funnits x antal till annonser som deleteas och ett visst antal nya har kommit.

Där av den lilla sql-satsen och det stora problemet


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-13 20:12:53 - Thomas Vanhaniemi

Som jag förstår det av sin SQL sats kan du förkorta ner den till åtminstone det här:
<code>
SELECT COUNT(0) FROM
(
(
SELECT DISTINCT custompropertyid FROM properties
WHERE customer = @CustomerID AND imported BETWEEN @StartDate AND @StopDate
)
UNION ALL
(
SELECT custompropertyid FROM properties
WHERE customer = @CustomerID AND imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)
)
) AS c
</code>
Testa och se om det ger samma resultat och är snabbare...


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-13 20:24:01 - Thomas Vanhaniemi

En till lösning, som kanske är ännu snabbare, kan vara
<code>
SELECT SUM(CASE WHEN a.imported IS NULL THEN a.antal ELSE 1 END) FROM
(
SELECT COUNT(0) AS antal, imported FROM properties
WHERE customer = @CustomerID AND (imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)) OR (imported BETWEEN @StartDate AND @StopDate)
GROUP BY custompropertyid
) AS a
</code>


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-13 22:40:19 - Fredrik Malmström

får testa och se om de blir snabbare, och om det returnerar rätt :)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-14 08:18:42 - Thomas Vanhaniemi

Kom just på att det saknas nog lite i den senaste SQL satsen jag skrev.
En lite modifierad variant kan vara:
<code>
SELECT SUM(CASE WHEN a.imported IS NULL THEN a.antal ELSE 1 END) FROM
(
SELECT COUNT(0) AS antal, imported FROM properties
WHERE customer = @CustomerID AND (imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)) OR (imported BETWEEN @StartDate AND @StopDate)
GROUP BY custompropertyid, imported IS NULL
) AS a
</code>


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-14 08:20:59 - Fredrik Malmström

Jag kan inte göra en sql-sats med en group by där den har värdet imported is null, jag får ett felmeddelande på IS.


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-14 08:21:45 - Thomas Vanhaniemi

Ok, men ta bort IS NULL då bara, det borde bli samma resultat ändå. Ville bara försöka spara in på raderna som returneras ;)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-14 08:22:51 - Thomas Vanhaniemi

Kanske du kan använda funktionen ISNULL(imported) istället


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-14 08:23:35 - Fredrik Malmström

mja.. det blir ca 1000 rader för många på senaste varianten :P


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-14 08:23:37 - Fredrik Malmström

mja.. det blir ca 1000 rader för många på senaste varianten :P


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-14 08:31:13 - Fredrik Malmström

nope isnull(imported) funkade inget vidare.

Men jag prövade den där andra (den första), den gjorde funktionen mycket snabbare de gånger jag nu har kört den... den nästan bara smällde till :)

skall utvärdera den ett tag och se om vi måste optimera ännu mer då. :)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-14 08:47:44 - Thomas Vanhaniemi

Akta så att datorn inte exploderar när det smäller ;)
Angående andra varianten ska jag, när jag får tid, ta och kontrollera den igen =)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-06-14 11:13:31 - Thomas Vanhaniemi

Har nu funderat lite och kommit fram till detta. Är inte säker på vad GROUP BY tycker om denna, men det borde fungera. Dessutom fanns det en parentes för lite så därför returnerade den tidigare versionen fel resultat.
<code>
SELECT SUM(CASE WHEN a.isnotimported THEN a.antal ELSE 1 END) FROM
(
SELECT COUNT(0) AS antal, (imported IS NULL) AS isnotimported FROM properties
WHERE customer = @CustomerID AND ((imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)) OR (imported BETWEEN @StartDate AND @StopDate))
GROUP BY custompropertyid, isnotimported
) AS a
</code>


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-06-27 10:34:05 - Thomas Vanhaniemi

Vad blev den bästa lösningen nu då?


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-07-03 08:09:46 - Fredrik Malmström

<code>select @Result = (select count(0) from
(
(
select distinct custompropertyid from properties
where customer=@CustomerID and imported between @StartDate and @StopDate
)
union all
(
select custompropertyid from properties
where customer=@CustomerID and imported is null and (deleted is null or deleted between @StartDate and @StopDate)
)
) as c)</code>
Denna blev det...

Snabbt och behändigt gick det!


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-07-03 09:00:37 - Thomas Vanhaniemi

Ok, bra =)

Testade du den andra varianten mer? Fungerade mina ändringar eller ger den ännu fel svar?
Bara lite nyfiken ;)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-07-03 09:08:01 - Fredrik Malmström

<code>SELECT SUM(CASE WHEN a.isnotimported THEN a.antal ELSE 1 END) FROM
(
SELECT COUNT(0) AS antal, (imported IS NULL) AS isnotimported FROM properties
WHERE customer = @CustomerID AND ((imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)) OR (imported BETWEEN @StartDate AND @StopDate))
GROUP BY custompropertyid, isnotimported
) AS a</code>


Denna ger felet:

Msg 4145, Level 15, State 1, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'THEN'.
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'IS'.


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-07-03 10:08:38 - Thomas Vanhaniemi

Ok, så den klagade på sånt =)
Nå, här är en modifierad variant som, enligt mitt tycke, borde fungera ;)
<code>
SELECT SUM(CASE WHEN a.imported IS NULL THEN a.antal ELSE 1 END) FROM
(
SELECT COUNT(0) AS antal, imported FROM properties
WHERE customer = @CustomerID AND ((imported IS NULL AND (deleted IS NULL OR deleted BETWEEN @StartDate AND @StopDate)) OR (imported BETWEEN @StartDate AND @StopDate))
GROUP BY custompropertyid, imported
) AS a
</code>


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-07-03 12:48:47 - Fredrik Malmström

den funkade i alla fall! :)


Svara

Sv:Seg user-defined scalar function.

Postades av 2007-07-03 15:38:04 - Thomas Vanhaniemi

Kul att veta! =)
Sen är frågan, är den snabbare, söligare eller lika snabb som den med union ;)


Svara

Sv: Seg user-defined scalar function.

Postades av 2007-07-06 16:01:23 - Fredrik Malmström

ja det återstår att se vid ett senare skede :)


Svara

Nyligen

  • 14:24 CBD regelbundet?
  • 14:23 CBD regelbundet?
  • 14:22 Har du märkt några verkliga fördel
  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 616
27 953
271 709
5 698
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies