2012-09-05 4 views
0

몇 주 전에 실행 한 후 1 분이 지난 쿼리는 이제 끝이 보이지 않아 10 분 이상 걸립니다.10 분 이상 걸리는 검색어에 삽입하십시오.

새 쿼리 (촬영시 LONG TIME)

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) 
+0

프로세스가 차단 되었습니까? 이 프로세스가 대기하도록하는 열려있는 트랜잭션이 있습니까? – goatshepard

+0

프로세스 목록을 질문에 넣습니다. 실행되는 유일한 쿼리이기 때문에 차단되지 않는 것 같습니다. –

답변

2

하위 쿼리를 사용하여 백분율을 계산하는 방식 때문에 SELECT가 매우 느리게 진행됩니다. 각 행에 대해 1 년 전체 데이터를 읽습니다. 하위 쿼리를 사용하여 합계를 선택하고 조인하면 훨씬 빠르게 실행됩니다. 내 머리,이 같은의 상단 오프

는 (동안 이상적이지) 기존의 쿼리보다 훨씬 더 빨리해야 다음 SELECT 쿼리에

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 
+1

'ROUND ((detail.count/summary.total) * 100, 2) %로 ' – edze

+0

죄송합니다. 나는 그것을 지금 고쳤다. –

+0

원래 질문으로 게시 한 관련 검색어를 볼 수 있습니까? 나는 지역별로 그룹화하려고 노력하고 있으며 같은 패턴을 사용하려고했지만 정말 느립니다. –

0

하자의 작품. 이 조각을 한 장씩 보겠습니다. 각기 다른 학교, 인종 및 연도별로 한 행을 원하는 것처럼 보입니다. 그것은 간단합니다.

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 측정 항목을 정리해 보겠습니다. 귀하의 질문에서 정확하게 말하기는 어렵지만, 나는 추측 할 것입니다. 각 경주에 속한 학생의 비율을 원하는 것처럼 보입니다.

두 가지 요약 쿼리를 ​​사용해야합니다. 하나는 각 학교의 총 학생 수를 1 년으로줍니다.

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

두 번째 숫자는 학교, 연도 및 인종별로 총 학생 수를 나타냅니다. 그들은 가상 테이블 인 것처럼

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 

그런 다음, 우리는이 두 가지 쿼리에 가입해야합니다, 그래서 우리는 분수 수행 할 수 있습니다

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) 
관련 문제