2012-09-05 22 views
0

幾周前我跑了一分鐘後,查詢花了1分鐘,現在花了10分鐘,看不到任何結果。插入到超過10分鐘的select查詢中

新的查詢(需要長時間)

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將會非常慢。它正在讀取每行的全年數據。如果您使用子查詢來選擇總計並加入,那麼它應該運行得更快。

了我的頭,像這樣的頂部(而不是理想的)應該是速度遠遠超過現有查詢:

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查詢工作。讓我們一塊一塊地做。看起來你需要爲每一個不同的學校,種族和年份劃一行。這很簡單。

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度量標準。很難從你的問題中確切地知道它是什麼,但我會猜測。看起來你想要的是屬於每場比賽的學生比例。

所以我們需要處理兩個彙總查詢。一個給我們每年每所學校的學生總數。

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)