简体   繁体   中英

MySQL Group running too slow

I have a 3 MySQL tables which I need to get results from and which are:

1. Towns
Fields Towncode and Townname

2. Students
Fields student_id,name,surname,address,streetcode,towncode,HeadOfFamily

3. Phonebank
Fields student_id,contacted,towncode

Now I need a mysql statement (a) to get the total number of households from the students table and also (b) the number of students contacted for that particular town.

up to step (a) I managed which and is extremely fast which is:

SELECT 
      t.towncode as towncode, 
      t.townname as townname, 
      (SELECT COUNT(*) 
          FROM students p 
          WHERE p.towncode=t.towncode 
            and p.student_hh='H') AS households
   FROM 
      towns t 
   ORDER BY 
      t.towncode ASC 

but I cannot manage to insert as well another SELECT STATEMENT to get the number of calls fr that particular town.

Can you kindly assist please?

Doing a per-record count on towns is probably hurting you. I would pre-query the students table first, THEN use that joined to the towns.

For indexes, I would have the following indexes

table      index
towns      ( towncode, townname )
students   ( student_hh, towncode )

SELECT 
      t.towncode as towncode, 
      t.townname as townname, 
      TownCnts.households
   FROM 
      towns t 
         JOIN ( SELECT 
                      p.towncode,
                      COUNT(*) households
                   from
                      students p
                   where
                      p.student_hh = 'H'
                   group by 
                      p.towncode ) as TownCnts
           ON t.towncode = TownCnts.towncode
   ORDER BY 
      t.towncode ASC 

Assuming that the number of "calls" is the number of rows in the PhoneBank table with a particular town code, then you can add another subselect:

SELECT t.towncode as towncode, t.townname as townname, 
       (SELECT COUNT(*) 
        FROM students p 
        WHERE p.towncode = t.towncode and p.student_hh='H'
       ) AS households,
       (SELECT COUNT(*) 
        FROM phonebank pb
        WHERE pb.towncode = t.towncode 
       ) AS calls
FROM towns t 
ORDER BY t.towncode ASC ;

Your question is a little vague. It is possible that you want count(distinct studentid) in the second query, rather than count(*) .

To optimize this query, create the following indexes:

  • towns(towncode)
  • students(towncode, student_hh)
  • phonebank(towncode)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM