0

数週間前に実行したときは 1 分もかからなかったクエリが、今では 10 分以上かかっており、終わりが見えません。

新しいクエリ (時間がかかります)

select sds.school_id, 
  detail.year, 
  detail.race,
  ROUND((detail.count / summary.total) * 100 ,2) as percent 
FROM school_data_race_ethnicity_raw as detail
inner join school_data_schools as sds USING (school_id)
inner join (
  select sds2.district_id, year, sum(count) as total
  from school_data_race_ethnicity_raw
  inner join school_data_schools as sds2 USING (school_id)
  group by sds2.district_id, year
  ) as summary on summary.district_id = sds.district_id 
    and summary.year = detail.year

クエリ:

INSERT INTO school_data_race_ethnicity_schools (school_id, year, race, percent) (
    SELECT school_id,
           year,
           race,
           ROUND((count/(
        SELECT SUM(count) 
          FROM school_data_race_ethnicity_raw as school_data_race_ethnicity_raw_inner 
         WHERE school_id = school_data_race_ethnicity_raw_outer.school_id 
           and year = school_data_race_ethnicity_raw_outer.year)
                        ) * 100,2) as percent
      FROM school_data_race_ethnicity_raw as school_data_race_ethnicity_raw_outer)    

説明:

mysql> explain SELECT school_id,year,race,ROUND((count/(SELECT SUM(count) 
    -> FROM school_data_race_ethnicity_raw as school_data_race_ethnicity_raw_inner 
    -> WHERE 
    -> school_id = school_data_race_ethnicity_raw_outer.school_id and 
    -> year = school_data_race_ethnicity_raw_outer.year)) * 100,2) as percent
    -> FROM school_data_race_ethnicity_raw as school_data_race_ethnicity_raw_outer;
+----+--------------------+--------------------------------------+------+----------------------------+------+---------+-----------------------------------------------------------------+-------+-------------+
| id | select_type        | table                                | type | possible_keys              | key  | key_len | ref                                                             | rows  | Extra       |
+----+--------------------+--------------------------------------+------+----------------------------+------+---------+-----------------------------------------------------------------+-------+-------------+
|  1 | PRIMARY            | school_data_race_ethnicity_raw_outer | ALL  | NULL                       | NULL | NULL    | NULL                                                            | 84012 |             |
|  2 | DEPENDENT SUBQUERY | school_data_race_ethnicity_raw_inner | ref  | school_id,year,school_id_2 | year | 4       | rocdocs_main_drupal_7.school_data_race_ethnicity_raw_outer.year |  8402 | Using where |
+----+--------------------+--------------------------------------+------+----------------------------+------+---------+-----------------------------------------------------------------+-------+-------------+
2 rows in set (0.00 sec)

テーブルを作成します。

mysql> show create table school_data_race_ethnicity_raw;
+--------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                          | Create Table                                                                                                                                                                                                                                                                                                                                                                                                  |
+--------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| school_data_race_ethnicity_raw | CREATE TABLE `school_data_race_ethnicity_raw` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `school_id` varchar(255) NOT NULL,
  `year` int(11) NOT NULL,
  `race` varchar(255) NOT NULL,
  `count` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `school_id` (`school_id`,`year`),
  KEY `year` (`year`,`race`),
  KEY `school_id_2` (`school_id`)
) ENGINE=MyISAM AUTO_INCREMENT=84013 DEFAULT CHARSET=latin1 |
+--------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table school_data_race_ethnicity_schools;
+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                              | Create Table                                                                                                                                                                                                                                                                                                                                                                           |
+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| school_data_race_ethnicity_schools | CREATE TABLE `school_data_race_ethnicity_schools` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `school_id` varchar(255) NOT NULL,
  `year` int(11) NOT NULL,
  `race` varchar(255) NOT NULL,
  `percent` decimal(15,2) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `year` (`year`,`race`),
  KEY `school_id` (`school_id`,`year`)
) ENGINE=MyISAM AUTO_INCREMENT=24961 DEFAULT CHARSET=latin1 |
+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


mysql> show processlist;
+------+---------+--------------------+-----------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| Id   | User    | Host               | db                    | Command | Time | State        | Info                                                                                                 |
+------+---------+--------------------+-----------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| 1739 | [REMOVED] |  [REMOVED] | rocdocs_main_drupal_7 | Query   | 1467 | Sending data | INSERT INTO school_data_race_ethnicity_schools (school_id, year, race, percent) (
SELECT school_id,y |
| 1800 | root    | localhost          | rocdocs_main_drupal_7 | Query   |    0 | NULL         | show processlist                                                                                     |
+------+---------+--------------------+-----------------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
4

2 に答える 2

2

Your SELECT is going to be very slow because of the way you are using a sub-query to calculate the percentages. It's reading an entire year's data for each row. If you use a sub-query to select the totals and join to that then it should run much faster.

Off the top of my head, something like this (while not ideal) should be much faster than your existing query:

select detail.school_id, 
  detail.year, 
  detail.race,
  ROUND((detail.count / summary.total) * 100 ,2) as percent 
FROM school_data_race_ethnicity_raw as detail
inner join (
  select school_id, year, sum(count) as total
  from school_data_race_ethnicity_raw
  group by school_id, year
  ) as summary on summary.school_id = detail.school_id 
    and summary.year = detail.year
于 2012-09-05T20:16:55.907 に答える
0

SELECTクエリに取り組みましょう。これを少しずつやっていきましょう。学校、人種、年ごとに 1 つの行が必要なようです。それは簡単です。

   SELECT r.school_id, r.year, r.race, something
     FROM school_data_race_ethnicity_raw r
    GROUP BY r.school_id, r.year, r.race

somethingそれでは、メトリックを整理しましょう。あなたの質問から正確にそれを伝えるのは難しいですが、私は推測します。各人種に属する学生の割合が必要なようです。

したがって、2 つの要約クエリを使用する必要があります。1 つは、各学校の学年別の生徒数の合計です。

  SELECT r.school_id, r.year, SUM(count) count
    FROM school_data_race_ethnicity_raw r
GROUP BY r.school_id, r.year

2 つ目は、学校、学年、人種ごとの生徒の総数です。

  SELECT r.school_id, r.year, r.race, SUM(count) count
    FROM school_data_race_ethnicity_raw r
GROUP BY r.school_id, r.year, r.race

次に、仮想テーブルであるかのように、これら 2 つのクエリを結合して、分数を計算できるようにする必要があります。

  SELECT t.school_id, t.year, u.race, u.count/t.count percent
     FROM 
     (
          SELECT r.school_id, r.year, SUM(count) count
            FROM school_data_race_ethnicity_raw r
        GROUP BY r.school_id, r.year
     ) t
     LEFT JOIN
     (
          SELECT r.school_id, r.year, r.race, SUM(count) count
            FROM school_data_race_ethnicity_raw r
        GROUP BY r.school_id, r.year, r.race
     ) u ON (t.school_id = u.school_id AND t.year = u.year)

最後に、パーセンテージが必要なので、分数に 100.0 を掛けましょう。

   SELECT t.school_id, t.year, u.race, ROUND(100.0*u.count/t.count, 2) percent
     FROM 
     (
          SELECT r.school_id, r.year, SUM(count) count
            FROM school_data_race_ethnicity_raw r
        GROUP BY r.school_id, r.year
     ) t
     LEFT JOIN
     (
          SELECT r.school_id, r.year, r.race, SUM(count) count
            FROM school_data_race_ethnicity_raw r
        GROUP BY r.school_id, r.year, r.race
     ) u ON (t.school_id = u.school_id AND t.year = u.year)
于 2012-09-05T20:34:28.497 に答える