0

アプリケーションのパフォーマンスを改善しようとしています。アプリの読み込みに時間がかからないように (5 ~ 10 秒)、cron で実行されるサマリー テーブルを作成する必要がある場合があります。それは最高のアイデアですか?

次の表を考えます。

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 ごとに 1 回実行)

このクエリは高速 (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                                  |
+----+--------------------+--------------------+------+----------------------------------+----------------+---------+-------+-------+----------------------------------------------+
4

1 に答える 1

-1

相関サブクエリ/サブセレクトは、多くの場合、ボトルネックになります。部分的には、MySql にはネストされたループ結合アルゴリズムしかなく、ハッシュ結合/マージ結合がないという事実が原因です。

メインの選択を、必要なすべての SUM 値を保持する派生テーブルに結合してみます。

于 2012-08-15T12:33:48.497 に答える