2012-08-15 3 views
0

응용 프로그램의 성능을 향상 시키려고합니다. cron에서 실행되는 요약 테이블을 만들어 앱이로드하는 데 오래 걸리지 않도록 (5 ~ 10 초) 필요할 수 있습니다. 그게 최선의 생각입니까?느린 mysql 쿼리를 가속

mysql> describe school_data_sets_numeric_data; 
+--------------+---------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+---------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| data_set_nid | int(11)  | NO | MUL | NULL |    | 
| school_nid | int(11)  | NO | MUL | NULL |    | 
| year   | int(11)  | NO | MUL | NULL |    | 
| description | varchar(255) | NO |  | NULL |    | 
| value  | decimal(18,5) | NO |  | NULL |    | 
+--------------+---------------+------+-----+---------+----------------+ 
6 rows in set (0.00 sec) 

그리고 다음 쿼리 (학교 각 data_set_nid에 대해 한 번 실행)

이 쿼리는 빠른 (0 초)를 실행합니다 :

SELECT year, description, CONCAT(FORMAT((value/(SELECT SUM(value) 
FROM `school_data_sets_numeric_data` as numeric_data_inner 
WHERE year = numeric_data_outer.year and data_set_nid = numeric_data_outer.data_set_nid and school_nid = numeric_data_outer.school_nid)) * 100, 2), '%') as value 
FROM `school_data_sets_numeric_data` as numeric_data_outer 
WHERE data_set_nid = 38251 and school_nid = 32805 ORDER BY id DESC; 

다음 표 감안할 때

설명 :

+----+--------------------+--------------------+------+---------------------------------------------+--------------+---------+-----------------------------------------------------------------------------------------------------------+------+-----------------------------+ 
| id | select_type  | table    | type | possible_keys        | key   | key_len | ref                          | rows | Extra      | 
+----+--------------------+--------------------+------+---------------------------------------------+--------------+---------+-----------------------------------------------------------------------------------------------------------+------+-----------------------------+ 
| 1 | PRIMARY   | numeric_data_outer | ref | data_set_nid,data_set_nid_2,school_nid  | data_set_nid | 8  | const,const                        | 17 | Using where; Using filesort | 
| 2 | DEPENDENT SUBQUERY | numeric_data_inner | ref | year,data_set_nid,data_set_nid_2,school_nid | data_set_nid | 8  | rocdocs_main_drupal_7.numeric_data_outer.data_set_nid,rocdocs_main_drupal_7.numeric_data_outer.school_nid | 9 | Using where     | 
+----+--------------------+--------------------+------+---------------------------------------------+--------------+---------+-----------------------------------------------------------------------------------------------------------+------+-----------------------------+ 

이 쿼리 실행 속도가 느린 (1.43 초) :

SELECT year, description, CONCAT(FORMAT((SUM(value)/(SELECT SUM(value) 
FROM `school_data_sets_numeric_data` as numeric_data_inner 
WHERE year = numeric_data_outer.year and data_set_nid = numeric_data_outer.data_set_nid)) * 100, 2), '%') as value 
FROM `school_data_sets_numeric_data` as numeric_data_outer 
WHERE data_set_nid = 38251 GROUP BY year,description ORDER BY id DESC; 

설명 :

+----+--------------------+--------------------+------+----------------------------------+----------------+---------+-------+-------+----------------------------------------------+ 
| id | select_type  | table    | type | possible_keys     | key   | key_len | ref | rows | Extra          | 
+----+--------------------+--------------------+------+----------------------------------+----------------+---------+-------+-------+----------------------------------------------+ 
| 1 | PRIMARY   | numeric_data_outer | ref | data_set_nid,data_set_nid_2  | data_set_nid_2 | 4  | const | 90640 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | numeric_data_inner | ref | year,data_set_nid,data_set_nid_2 | year   | 4  | func | 38871 | Using where         | 
+----+--------------------+--------------------+------+----------------------------------+----------------+---------+-------+-------+----------------------------------------------+ 
+0

테이블에 얼마나 많은 'school_nid'가 있습니까? – arnoudhgz

+0

5446 개의 다른 school_nids가 있습니다. –

답변

-1

상관 서브 쿼리/부속 선택은 종종 bottelneck입니다 - 부분적으로 MySQL은 단지 중첩 루프 조인 알고리즘을 가지고 있다는 사실에 해시 조인/병합 조인이 없습니다.

필자가 필요로하는 모든 SUM 값을 포함하는 파생 테이블에 기본 선택을 연결하려고합니다.

-1

해당 검색어에 대해 설명해 보셨습니까? 당신이 올바른 인덱스를 선택하는 데 도움이되지 않지만 "data_set_nid = numeric_data_outer.data_set_nid)) * 100, 2), '%')"는 아마도 가장 느린 부분 일 것입니다.

예제 :

지난주의 모든 데이터를 찾으십시오. 석회질이 분야에 있기 때문에

select * from mything where adddate(day, +7, mydate)>now 

, 그것은이 일정하기 때문에

select * from mything where mydate>adddate(day,-7,now) 

빠른 것

느려집니다.