webForumDet fria alternativet

Snygga till/snabba upp SQL-fråga

8 svar · 541 visningar · startad av phred

phredMedlem sedan nov. 2005314 inlägg
#1

Hej jag har en sql-fråga som ställs mot en sqlserver 2005 databas. Den fungerar, dock med ett mindre tillfredställande resultat, det menas att den tar väldigt lång tid att köra.

        SELECT ID, NAME, LOGIN, TIME_STAMP,
        case when HAS_SMS = 1 then 'JA' else 'NEJ' end as HASSMS, 
        'CustomerEdit.aspx?Customer=' + case when ACCESS_LEVEL = 3 then convert(varchar,PARENT_USER_ID) else convert(varchar,ID) end as LINK, 
        'CustomerSMS.aspx?Customer=' + case when ACCESS_LEVEL = 3 then convert(varchar,PARENT_USER_ID) else convert(varchar,ID) end as SMSLINK, 
        PASSWORD, COMPANY, 
        case when COUNTER.CountAddresses IS NULL then '0' else COUNTER.CountAddresses end As strCountAddresses, 
        case when MAXADDRESSES = 0 OR MAXADDRESSES IS NULL then 'Unlimited' else convert(varchar,MAXADDRESSES) end As strMaxAddresses, 
        (HAS_1 + HAS_2 + HAS_3 + HAS_4 + HAS_5 + HAS_6 + HAS_7) AS CountModules 
        FROM CUSTOMER C 
        LEFT JOIN 
        (SELECT DL.CUSTOMER_ID, COUNT(*) AS CountAddresses 
        FROM DISTRIBUTION_LIST DL INNER JOIN SUBSCRIBER S ON 
        S.DISTRIBUTION_LIST_ID = DL.ID 
        WHERE REGISTERED = 1 GROUP BY DL.CUSTOMER_ID) AS COUNTER ON C.ID = COUNTER.CUSTOMER_ID 
        where ACCESS_LEVEL <> 3 
        ORDER BY TIME_STAMP DESC

All hjälp uppskattas.

/F

@ndersMedlem sedan juni 200032 969 inlägg
#2

Om du rensar bort allt skräp som gör ditt inlägg kladdigt, och bara ger oss SQL-frågan så slipper det ta våra hjärnor onödigt lång tid att parsa koden...

Men, vad är det som tar tid? Vad händer om du de olika delarna för sig själv? Hur är tabellerna indexerade?

phredMedlem sedan nov. 2005314 inlägg
#3

Det som står inom kod-blocket är min sql-fråga, varken mer eller mindre.

@ndersMedlem sedan juni 200032 969 inlägg
#4

Det ser ut som att det är en massa ASP-kod eller liknande? citationstecken och märkliga radbrytningar med & _ som inte hör SQL till. Rensa bort så blir det lättare att läsa.

colioneMedlem sedan juni 20014 421 inlägg
#5

Response.Write sQuery

@ndersMedlem sedan juni 200032 969 inlägg
#6

colione skrev:

Response.Write sQuery

Passar inte så bra denna gång, eftersom man blir av med de fina raduppdelningarna, så på så sätt är frågan fin. Jag skulle tippa på att en manuell rensning gör jobbet finast. =)

snabelish skrev:

Men, vad är det som tar tid? Vad händer om du de olika delarna för sig själv? Hur är tabellerna indexerade?

I övrigt: har du analyserat med till exempel "Show execution plan" i Management studio?

phredMedlem sedan nov. 2005314 inlägg
#7

har fixat lite med koden i originalinlägget.

har även kört "Show execution plan" men det är rena grekiskan för mig, kan jag läsa nånstans vad det jag får ut betyder ? (http://www.kokkis.se/exPlan.gif) Logg finns att få om det gör någon skillnad.

Har även kört något som heter SHOWPLAN_ALL ON och det har gett mig följande resultat http://www.kokkis.se/showplan_all.csv som om möjligt är ännu krångligare att förstå :)

Det jag "tror" tar tid är den delen som innehåller:

COUNT(*) AS CountAddresses

EDIT*
Hittade detta:

Clustered Index Scan: A clustered index scan is like a table scan, except that it is done on a table that has a clustered index. Like a regular table scan, a clustered index scan may indicate a performance problem. Generally, they occur for two different reasons. First, there may be too many rows to retrieve, relative to the total number of rows in the table. See the "Estimated Row Count" to verify this. Second, it may be due to the column queried in the WHERE clause may not be selective enough. In any event, a clustered index scan is generally faster than a standard table scan, as not all records in the table always have to be searched when a clustered index scan is run, unlike a standard table scan. Generally, the only thing you can do to change a clustered index scan to a clustered index seek is to rewrite the query so that it is more restrictive and fewer rows are returned.

Som jag förstår detta så är det enda sättet att skriva om frågan så den returnerar mindre antal rader för att uppnå en "clustered index seek" istället för en "clustered index scan" ?

überfuzzMedlem sedan apr. 2006409 inlägg
#8

Du kanske skulle ta och visa tabellstrukturen och beskriva vad du vill göra... Det jag kan säga efter att tittat på din query är att den ser grötig ut.

phredMedlem sedan nov. 2005314 inlägg
#9

überfuzz skrev:

Det jag kan säga efter att tittat på din query är att den ser grötig ut.

No shit sherlock ;)

CREATE TABLE [CUSTOMER](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[LOGIN] [nvarchar](20) COLLATE Finnish_Swedish_CI_AS NOT NULL,
	[PASSWORD] [nvarchar](50) COLLATE Finnish_Swedish_CI_AS NULL,
	[ACCESS_LEVEL] [tinyint] NULL,
	[PARENT_USER_ID] [int] NULL,
	[NAME] [nvarchar](50) COLLATE Finnish_Swedish_CI_AS NULL,
	[EMAIL] [nvarchar](50) COLLATE Finnish_Swedish_CI_AS NULL,
	[TIME_STAMP] [datetime] NULL DEFAULT (getdate()),
	[HAS_NEWSLETTER] [tinyint] NULL DEFAULT (0),
	[HAS_STATISTIC] [tinyint] NULL DEFAULT (0),
	[HAS_DYNAMICFUNCTION] [tinyint] NULL DEFAULT (0),
	[HAS_TRACKING] [tinyint] NULL DEFAULT (0),
	[HAS_SMS] [tinyint] NULL DEFAULT (0),
	[HAS_QUESTIONAIRE] [tinyint] NULL DEFAULT (0),
	[HAS_SUPPORT] [tinyint] NULL CONSTRAINT DEFAULT (0),
	[COMPANY] [varchar](100) COLLATE Finnish_Swedish_CI_AS NULL,
	[MAXADDRESSES] [int] NULL
CREATE TABLE [DISTRIBUTION_LIST](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[CUSTOMER_ID] [int] NULL,
	[TITLE] [nvarchar](50) COLLATE Finnish_Swedish_CI_AS NULL,
	[TIME_STAMP] [datetime] NULL CONSTRAINT  DEFAULT (getdate())
CREATE TABLE [SUBSCRIBER](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[UNIQUE_ID] [uniqueidentifier] NULL DEFAULT (newid()),
	[EMAIL] [nvarchar](100) COLLATE Finnish_Swedish_CI_AS NULL,
	[DISTRIBUTION_LIST_ID] [int] NULL,
	[TIME_STAMP] [datetime] NULL DEFAULT (getdate()),
	[FIRST_NAME] [nvarchar](200) COLLATE Finnish_Swedish_CI_AS NULL,
	[SURNAME] [nvarchar](200) COLLATE Finnish_Swedish_CI_AS NULL,
	[TITLE] [nvarchar](100) COLLATE Finnish_Swedish_CI_AS NULL,
	[COMPANY] [nvarchar](200) COLLATE Finnish_Swedish_CI_AS NULL

Det jag vill hämta ut är följande:

ID,NAME,LOGIN,PASSWORD,COMPANY,TIME_STAMP från customer och så vill jag räkna ut hur många SUBSCRIBERS det finns som tillhör en DISTRIBUTION_LIST som tillhör CUSTOMER_ID.

Det är i stort vad jag vill göra, de andra case grejjerna är mest för att få ut en korrekt länk osv.

Säg till om det är nåt mer jag behöver skicka med för att det ska bli lättare.

126 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
124 ms — hämta tråd, inlägg och bilagor (db)