MySQL视图花费太多时间来选择数据

时间:2013-01-21 10:31:27

标签: mysql view query-optimization

在我正在处理的网页中,我需要根据三个表中的不同用户详细信息显示一些统计信息。所以我有以下查询,我加入到更多不同的表:

SELECT *
FROM `user` `u`
LEFT JOIN `subscriptions` `s` ON `u`.`user_id` = `s`.`user_id`
LEFT JOIN `devices` `ud` ON `u`.`user_id` = `ud`.`user_id`
GROUP BY `u`.`user_id`

当我使用LIMIT 1000执行查询时,它需要 0.05 秒,因为我在很多查询中使用了所有三个表中的数据,所以我决定放入它位于VIEW

CREATE VIEW `user_details` AS ( the same query from above )

现在我跑的时候:

SELECT * FROM user_details LIMIT 1000

需要 7-10 秒。

所以我的问题是我可以做些什么来优化视图,因为查询似乎很快或者我应该是整个查询而不是视图?

编辑:这是EXPLAIN SELECT * FROM user_details返回的内容

+----+-------------+------------+--------+----------------+----------------+---------+------------------------+--------+-------+
| id | select_type | table      | type   | possible_keys  | key            | key_len | ref                    | rows   | Extra |
+----+-------------+------------+--------+----------------+----------------+---------+------------------------+--------+-------+
|  1 | PRIMARY     | <derived2> | ALL    | NULL           | NULL           | NULL    | NULL                   | 322666 |       |
|  2 | DERIVED     | u          | index  | NULL           | PRIMARY        | 4       | NULL                   | 372587 |       |
|  2 | DERIVED     | s          | eq_ref | PRIMARY        | PRIMARY        | 4       | db_users.u.user_id     |      1 |       |
|  2 | DERIVED     | ud         | ref    | device_id_name | device_id_name | 4       | db_users.u.user_id     |      1 |       |
+----+-------------+------------+--------+----------------+----------------+---------+------------------------+--------+-------+

4行(8.67秒)

这是explain为查询返回的内容:

+----+-------------+-------+--------+----------------+----------------+---------+------------------------+--------+-------+
| id | select_type | table | type   | possible_keys  | key            | key_len | ref                    | rows   | Extra |
+----+-------------+-------+--------+----------------+----------------+---------+------------------------+--------+-------+
|  1 | SIMPLE      | u     | index  | NULL           | PRIMARY        | 4       | NULL                   | 372587 |       |
|  1 | SIMPLE      | s     | eq_ref | PRIMARY        | PRIMARY        | 4       | db_users.u.user_id     |      1 |       |
|  1 | SIMPLE      | ud    | ref    | device_id_name | device_id_name | 4       | db_users.u.user_id     |      1 |       |
+----+-------------+-------+--------+----------------+----------------+---------+------------------------+--------+-------+

设置3行(0.00秒)

1 个答案:

答案 0 :(得分:2)

如果涉及性能,则视图和联接非常糟糕。对于所有关系数据库管理系统,这或多或少都是正确的。听起来很奇怪,因为这就是那些系统的设计目标,但它确实如此。

如果这是一个在页面上使用频繁的查询,请尝试避免连接:而是创建一个从三个表中填充的真实表(不是视图)。您可以使用触发器自动执行该过程。因此,每次将条目插入原始表的oe时,触发器都会将数据传播到物理user_details表。

这种策略无疑意味着对设置进行一次性投资,但您肯定会获得更多更好的性能。