webForumDet fria alternativet

SQL optimering

4 svar · 627 visningar · startad av Zida

ZidaMedlem sedan juni 20108 inlägg
#1

Har följande fråga som jag skulle behöva hjälp med:

SELECT COUNT(tblRegistrations.regId) AS regCount, tblCourses.courseId, 
tblCourses.centerId, tblCourses.courseName,tblCourses.courseDayTime, tblCourses.courseActive, tblCourses.courseMaxRegistrations 
FROM tblCourses 
INNER JOIN tblCenter ON tblCourses.centerId = tblCenter.centerId 
LEFT JOIN tblRegistrations ON tblregistrations.regCourseId = tblCourses.courseId 
AND tblRegistrations.regTransactionStatus <> 'Failed' 
WHERE courseExpire >= '" + currentDate + "' AND tblCenter.siteId = 2 
GROUP BY tblCourses.courseId 
ORDER BY tblCourses.courseSortOrder

I det här läget är den just nu ganska långsam, ändrar jag min LEFT JOIN till INNER JOIN går det blixtsnabbt. Problemet är då att den inte tar med de kurser som har 0 registreringar.

Någon som har ett bra förslag?

nitro2k01Medlem sedan aug. 20037 630 inlägg
#2

Mer läsligt:

SELECT COUNT(tblRegistrations.regId) AS regCount, tblCourses.courseId, tblCourses.centerId, 
    tblCourses.courseName,tblCourses.courseDayTime, tblCourses.courseActive, tblCourses.courseMaxRegistrations 
FROM tblCourses 
INNER JOIN tblCenter ON tblCourses.centerId = tblCenter.centerId 
LEFT JOIN tblRegistrations ON tblregistrations.regCourseId = tblCourses.courseId AND tblRegistrations.regTransactionStatus <> 'Failed' 
WHERE courseExpire >= '" + currentDate + "' AND tblCenter.siteId = 2 
GROUP BY tblCourses.courseId 
ORDER BY tblCourses.courseSortOrder

Du kan prova att hämta antalet med en subselect...

SELECT 
(SELECT COUNT(tblRegistrations.regId) FROM tblRegistrations WHERE tblregistrations.regCourseId = tblCourses.courseId AND tblRegistrations.regTransactionStatus <> 'Failed') AS regCount, 
tblCourses.courseId, tblCourses.centerId, tblCourses.courseName,tblCourses.courseDayTime, tblCourses.courseActive, tblCourses.courseMaxRegistrations 
FROM tblCourses 
INNER JOIN tblCenter ON tblCourses.centerId = tblCenter.centerId 
WHERE courseExpire >= '" + currentDate + "' AND tblCenter.siteId = 2 
GROUP BY tblCourses.courseId 
ORDER BY tblCourses.courseSortOrder

Om det inte hjälper är den bästa lösningen att lagra antalet registreringar i en kolumn i tblCourses, och uppdatera vartefter när du lägger till eller tar bort rader i tblRegistrations.

Du bör kunna göra detta och initialt sätta alla värden rätt med typ:

ALTER TABLE tblCourses ADD COLUMN regCounts mediumint NOT NULL DEFAULT 0;

UPDATE tblCourses SET regCounts = (SELECT COUNT(tblRegistrations.regId) FROM tblRegistrations WHERE tblregistrations.regCourseId = tblCourses.courseId AND tblRegistrations.regTransactionStatus <> 'Failed');
ZidaMedlem sedan juni 20108 inlägg
#3

Tack för ditt snabba svar!

Subselect har jag testat i ett par varianter men det gav ingen tydlig förbättring.

Någon som vet något annat alternativ eller är det i så fall bara att spara antalet i en kolumn? Skulle helst vilja slippa det alternativet.

CompusaMedlem sedan jan. 20022 952 inlägg
#4

Har du indexerat dina främmande nycklar, samt regid vilken du kör count på?

Här finns lite mer tips att tänka på när det gäller prestanda och joins:
http://www.sql-server-performance.com/tips/tuning_joins_p1.aspx

Om du använder SQL Server skulle du även kunna kika på indexerade vyer.

siloMedlem sedan nov. 200175 inlägg
#5

Nåt sånt här, fast har ingen aning om det är snabbare eller inte.

CREATE TABLE #temporarympRegistrations (regCourseId int, regCount int)

INSERT INTO #temporarympRegistrations(regCourseId, regCount)
SELECT regCourseId, COUNT(regId)
FROM tblRegistrations
WHERE (regTransactionStatus <> 'Failed')
GROUP BY regCourseId

SELECT #temporarympRegistrations.regCount AS regCount, tblCourses.courseId, tblCourses.centerId, 
    tblCourses.courseName,tblCourses.courseDayTime, tblCourses.courseActive, tblCourses.courseMaxRegistrations 
FROM tblCourses 
INNER JOIN tblCenter ON tblCourses.centerId = tblCenter.centerId 
INNER JOIN #temporarympRegistrations ON #temporarympRegistrations.regCourseId = tblCourses.courseId
WHERE courseExpire >= '" + currentDate + "' AND tblCenter.siteId = 2 
GROUP BY tblCourses.courseId 
ORDER BY tblCourses.courseSortOrder

DROP TABLE #temporarympRegistrations
Genererad på 370 ms · cache AV · v20260730165559-full.f96bc7eb