MySql重写子查询加入

时间:2013-03-04 03:33:31

标签: mysql sql query-optimization

我对此查询有疑问:

SELECT Group_concat(DISTINCT titlegredcd) 
       targetGroup, 
       tblevent.id, 
       generalsubcategorynm, 
       generalcategorynm, 
       coursename, 
       (SELECT Count(*) 
        FROM   tblinternalstudent, 
               tblstaff 
        WHERE  eventid = tblevent.id 
               AND tblinternalstudent.staffnoic = tblstaff.staffnoic) Total, 
       Date_format(startdate, '%d %b') 
       startdateDisplay, 
       Date_format(enddate, '%d %b') 
       enddateDisplay, 
       class, 
       organizer, 
       subcategorymainorder, 
       subcategorysuborder, 
       tblrefgeneralsubcategory.generalcategorycd, 
       tblrefgeneralsubcategory.generalsubcategorycd 
FROM   tblevent, 
       tblcourse, 
       tblrefgeneralsubcategory, 
       tblrefgeneralcategory, 
       tblinternalstudent a, 
       tblstaff b 
WHERE  tblrefgeneralsubcategory.generalcategorycd IN 
       ( 'G0001', 'G0002', 'G0003' ) 
       AND tblcourse.generalcategorycd = 
           tblrefgeneralsubcategory.generalcategorycd 
       AND tblcourse.generalsubcategorycd = 
           tblrefgeneralsubcategory.generalsubcategorycd 
       AND tblevent.courseid = tblcourse.courseid 
       AND tblrefgeneralsubcategory.generalcategorycd = 
           tblrefgeneralcategory.generalcategorycd 
       AND a.eventid = tblevent.id 
       AND a.staffnoic = b.staffnoic 
       AND startdate >= '2012-01-01' 
       AND enddate <= '2012-12-31' 
GROUP  BY tblevent.id, 
          generalsubcategorynm, 
          generalcategorynm, 
          coursename, 
          total, 
          startdatedisplay, 
          enddatedisplay, 
          class, 
          organizer, 
          subcategorymainorder, 
          subcategorysuborder, 
          tblrefgeneralsubcategory.generalcategorycd, 
          tblrefgeneralsubcategory.generalsubcategorycd 
ORDER  BY tblrefgeneralsubcategory.generalsubcategorycd, 
          coursename 

处理大约需要30分钟,我怀疑问题来自子选择。

我尝试使用join重写:

SELECT e.id, 
       e.courseid, 
       internalstaff.targetgroup, 
       internalstaff.total, 
       Date_format(startdate, '%d %b') AS startdateDisplay, 
       Date_format(enddate, '%d %b')   AS enddateDisplay, 
       class, 
       organizer, 
       coursename, 
       gs.generalcategorycd, 
       gs.generalsubcategorycd, 
       gs.generalsubcategorynm, 
       gs.subcategorymainorder, 
       gs.subcategorysuborder, 
       generalcategorynm 
FROM   tblcourse c, 
       tblrefgeneralsubcategory gs, 
       tblrefgeneralcategory g, 
       tblevent e 
       JOIN (SELECT i.eventid, 
                    Count(*)                           AS Total, 
                    Group_concat(DISTINCT titlegredcd) AS TargetGroup 
             FROM   tblinternalstudent i, 
                    tblstaff s 
             WHERE  i.staffnoic = s.staffnoic 
             GROUP  BY i.eventid) AS internalstaff 
         ON internalstaff.eventid = e.id 
WHERE  e.courseid = c.courseid 
       AND gs.generalcategorycd = g.generalcategorycd 
       AND gs.generalcategorycd IN ( 'G0001', 'G0002', 'G0003' ) 
       AND c.generalcategorycd = gs.generalcategorycd 
       AND c.generalsubcategorycd = gs.generalsubcategorycd 
       AND startdate >= '2012-01-01' 
       AND enddate <= '2012-12-31' 
GROUP  BY e.id, 
          generalsubcategorynm, 
          generalcategorynm, 
          startdatedisplay, 
          enddatedisplay, 
          class, 
          organizer, 
          subcategorymainorder, 
          subcategorysuborder, 
          generalcategorycd, 
          generalsubcategorycd 
ORDER  BY generalsubcategorycd, 
          coursename 

加载速度更快,并返回正确数量的记录作为原始查询(1802)。但是,当我在internalstaff表中添加BranchCd(和branchcd ='some branch code')时,它将返回较少数量的记录(519)。

但是在原始查询中,如果将(和branchcd ='some branch code')添加到sub select中,则返回正确数量的记录。

任何人都可以请教如何重写连​​接,以便它像子选择一样工作吗?

谢谢。

编辑: 对不起忘了包括表格:

tblinternalstudent (**staffnoic**, eventid)
tblstaff (**staffnoic** titlegredcd, branchcd, unitcd)
tblevent (**id**, courseid, startdate, enddate, class, organizer)
tblcourse (**courseid**, coursename)
tblrefgeneralcategory (**generalcategorycd**, generalcategorynm)
tblrefgeneralsubcategory (**generalsubcategorycd, generalsubcategorynm, generalcategorycd,subcategorymainorder, subcategorysuborder)

原始查询的EXPLAIN:

*************************** 1. row ***************************
       id: 1
       select_type: PRIMARY
       table: a
       type: ALL
       possible_keys: NULL
       key: NULL
       key_len: NULL
       ref: NULL
       rows: 38760
       Extra: Using temporary; Using filesort
*************************** 2. row ***************************
       id: 1
       select_type: PRIMARY
       table: b
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 44
       ref: edu_db.a.StaffNoIC
       rows: 1
       Extra: Using where
*************************** 3. row ***************************
       id: 1
       select_type: PRIMARY
       table: tblEvent
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 32
       ref: edu_db.a.EventId
       rows: 1
       Extra: Using where
*************************** 4. row ***************************
       id: 1
       select_type: PRIMARY
       table: tblcourse
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 30
       ref: edu_db.tblEvent.courseid
       rows: 1
       Extra: Using where
*************************** 5. row ***************************
       id: 1
       select_type: PRIMARY
       table: tblRefGeneralSubCategory
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 34
       ref: edu_db.tblcourse.GeneralSubCategoryCd,edu_db.tblcourse.GeneralCategoryCd
       rows: 1
       Extra:
*************************** 6. row ***************************
       id: 1
       select_type: PRIMARY
       table: tblRefGeneralCategory
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 17
       ref: edu_db.tblcourse.GeneralCategoryCd
       rows: 1
       Extra:
*************************** 7. row ***************************
       id: 2
       select_type: DEPENDENT SUBQUERY
       table: tblinternalstudent
       type: ALL
       possible_keys: NULL
       key: NULL
       key_len: NULL
       ref: NULL
       rows: 38760
       Extra: Using where
*************************** 8. row ***************************
       id: 2
       select_type: DEPENDENT SUBQUERY
       table: tblStaff
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 44
       ref: edu_db.tblinternalstudent.StaffNoIC
       rows: 1
       Extra: Using where; Using index

EXPLAIN for second query:

*************************** 1. row ***************************
       id: 1
       select_type: PRIMARY
       table: <derived2>
       type: ALL
       possible_keys: NULL
       key: NULL
       key_len: NULL
       ref: NULL
       rows: 8849
      Extra: Using temporary; Using filesort
*************************** 2. row ***************************
       id: 1
       select_type: PRIMARY
       table: e
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 32
       ref: internalstaff.eventid
       rows: 1
      Extra: Using where
*************************** 3. row ***************************
       id: 1
       select_type: PRIMARY
       table: c
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 30
       ref: edu_db.e.courseid
       rows: 1
       Extra: Using where
*************************** 4. row ***************************
       id: 1
       select_type: PRIMARY
       table: gs
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 34
       ref: edu_db.c.GeneralSubCategoryCd,edu_db.c.GeneralCategor
       rows: 1
       Extra:
*************************** 5. row ***************************
       id: 1
       select_type: PRIMARY
       table: g
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 17
       ref: edu_db.gs.GeneralCategoryCd
       rows: 1
       Extra: Using where
*************************** 6. row ***************************
       id: 2
       select_type: DERIVED
       table: i
       type: ALL
       possible_keys: NULL
       key: NULL
       key_len: NULL
       ref: NULL
       rows: 38760
       Extra: Using filesort
*************************** 7. row ***************************
       id: 2
       select_type: DERIVED
       table: s
       type: eq_ref
       possible_keys: PRIMARY
       key: PRIMARY
       key_len: 44
       ref: edu_db.i.StaffNoIC
       rows: 1

1 个答案:

答案 0 :(得分:0)

尝试此查询也可能存在一些关系问题,因为您在此处没有明确说明。

SELECT
  te.id,
  Date_format(startdate, '%d %b') AS startdateDisplay,
  Date_format(enddate, '%d %b') AS enddateDisplay,
  te.class,
  te.organizer,
  tgs.generalcategorycd,
  tgs.generalsubcategorycd,
  tgs.generalsubcategorynm,
  tgs.subcategorymainorder,
  tgs.subcategorysuborder,
  trc.generalcategorynm,
  count(tic.*)             AS `Total`,
  GROUP_CONCAT(DISTINCT tic. titlegredcd) AS TargetGroup
FROM tblevent AS te
  LEFT JOIN tblinternalstudent AS tis
    ON tis.eventid = te.id
  LEFT JOIN tblstaff AS ts
    ON ts.staffnoic = tis.staffnoic
  LEFT JOIN tblcourse AS tc
    ON tc.courseid = te.courseid
  LEFT JOIN tblrefgeneralsubcategory AS tgs
    ON tgs.generalcategorycd = tc.generalcategorycd
  LEFT JOIN tblrefgeneralcategory AS trc
    ON trc.generalcategorycd = tgs.generalcategorycd
WHERE te.startdate >= '2012-01-01'
    AND te.enddate <= '2012-12-31'
    AND trc.generalcategorycd IN('G0001', 'G0002', 'G0003')
GROUP BY te.id, tgs.generalsubcategorynm, trc.generalcategorynm, te.startdatedisplay, te.enddatedisplay te.class, te.organizer, tgs.subcategorymainorder, tgs.subcategorysuborder, trc.generalcategorycd, tgs.generalsubcategorycd
ORDER BY tgs.generalsubcategorycd, tc.coursename