webForumDet fria alternativet

Optimera SQL fråga

Databaser & SQL

3 svar · 651 visningar · startad av Zida

Medlem sedan juni 20108 inlägg
Frågan#1

Har stött på följande fråga som är riktigt långsam. Hur kan den smidigast optimeras på bästa sätt? Tacksam om någon har tid att hjälpa till :)

SELECT (SELECT COUNT(tblRegistrations.regId) FROM tblRegistrations WHERE tblRegistrations.regId IN (SELECT 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 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
Medlem sedan jan. 20023 327 inlägg
#2

Rent spontant skulle jag testa med EXISTS istället för IN (se nedan):

SELECT 
(
    SELECT 
        COUNT(tblRegistrations.regId) 
    FROM 
        tblRegistrations 
    WHERE [b]EXISTS[/b] 
    (
        SELECT 
            [b]*[/b]
        FROM 
            tblRegistrations
        WHERE
            tblregistrations.regCourseId = tblCourses.courseId AND tblRegistrations.regTransactionStatus <> 'Failed')
    ) 
    AS regCount, tblCourses.courseId, tblCourses.centerId, tblCourses.courseName, tblCourses.courseDayTime, tblCourses.courseActive 
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
Medlem sedan juni 20108 inlägg
#3

Tack för ett snabbt svar!

Dessvärre verkar det inte hjälpa, nu står den bara och väntar och laddar inte alls. Alternativt tar många gånger så lång tid som tidigare (och då var det redan långsamt)

Någon annan idé?

Medlem sedan aug. 20039 340 inlägg
#4

Hej och välkommen till webForum, Zida. Två tips:
För att göra koden mer läsbar, både för dig och andra, dela gärna upp den på flera rader. Sen en liten "wF-hemlighet". Det finns BBCode-taggar för att syntaxfärga kod, som synes nedan. Klicka på citera för att se hur jag gjorde.

Så här ser din ursprungskod ut efter lite omformatering:

SELECT (
    SELECT COUNT(tblRegistrations.regId) 
    FROM tblRegistrations 
    WHERE tblRegistrations.regId IN (
        SELECT 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
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

Hursomhaver, din beräkning är ett klockrent fall för en LEFT JOIN. En LEFT skiljer sig från en INNER i det att den JOIN-operationen tillåts ha 0 träffar, och då får COUNTen värdet 0.

SELECT 
  COUNT(tblRegistrations.regId), tblCourses.courseId, tblCourses.centerId,
  tblCourses.courseName,tblCourses.courseDayTime, tblCourses.courseActive
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
609 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849
133 ms — deklarationer (db)
121 ms — hämta statistik (db)
134 ms — hämta tråd, inlägg och bilagor (db)
352 ms — ändringar (db)