原文链接:
原文作者:maclochlainn
在mysql视图这一章中,我用两种方式编写了查询来介绍sql调优的思想。 这是介绍json类型之前的最后一个主题。
在解释了如何使用explain语法之后,我给了学生这个基于sakila示例数据库的查询。 查询只使用内部连接,根据经验,内部连接通常比子查询更快、更高效。
select ctry.country as country_name
, sum(p.amount) as tot_payments
from city c inner join address a
on c.city_id = a.city_id inner join customer cus
on a.address_id = cus.address_id inner join payment p
on cus.customer_id = p.customer_id inner join country ctry
on c.country_id = ctry.country_id
group by ctry.country;
它生成了以下表格式的执行计划输出:
---- ------------- ------- ------------ -------- --------------------------- -------------------- --------- ------------------------ ------ ---------- ------------------------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
---- ------------- ------- ------------ -------- --------------------------- -------------------- --------- ------------------------ ------ ---------- ------------------------------
| 1 | simple | cus | null | index | primary,idx_fk_address_id | idx_fk_address_id | 2 | null | 599 | 100.00 | using index; using temporary |
| 1 | simple | a | null | eq_ref | primary,idx_fk_city_id | primary | 2 | sakila.cus.address_id | 1 | 100.00 | null |
| 1 | simple | c | null | eq_ref | primary,idx_fk_country_id | primary | 2 | sakila.a.city_id | 1 | 100.00 | null |
| 1 | simple | ctry | null | eq_ref | primary | primary | 2 | sakila.c.country_id | 1 | 100.00 | null |
| 1 | simple | p | null | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | sakila.cus.customer_id | 26 | 100.00 | null |
---- ------------- ------- ------------ -------- --------------------------- -------------------- --------- ------------------------ ------ ---------- ------------------------------
5 rows in set, 1 warning (0.02 sec)
然后,我使用mysql工作台生成以下可视化执行计划:
然后,我将其与在select-list中使用相关子查询的重构查询版本进行比较。 这个例子来自于alan beaulieu的《学习sql,第三版》的附录b。
select ctry.country
, (select sum(p.amount)
from city c inner join address a
on c.city_id = a.city_id inner join customer cus
on a.address_id = cus.address_id inner join payment p
on cus.customer_id = p.customer_id
where c.country_id = ctry.country_id) as tot_payments
from country ctry;
它生成了以下表格执行计划输出:
---- -------------------- ------- ------------ ------ --------------------------- -------------------- --------- ------------------------ ------ ---------- -------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
---- -------------------- ------- ------------ ------ --------------------------- -------------------- --------- ------------------------ ------ ---------- -------------
| 1 | primary | ctry | null | all | null | null | null | null | 109 | 100.00 | null |
| 2 | dependent subquery | c | null | ref | primary,idx_fk_country_id | idx_fk_country_id | 2 | sakila.ctry.country_id | 5 | 100.00 | using index |
| 2 | dependent subquery | a | null | ref | primary,idx_fk_city_id | idx_fk_city_id | 2 | sakila.c.city_id | 1 | 100.00 | using index |
| 2 | dependent subquery | cus | null | ref | primary,idx_fk_address_id | idx_fk_address_id | 2 | sakila.a.address_id | 1 | 100.00 | using index |
| 2 | dependent subquery | p | null | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | sakila.cus.customer_id | 26 | 100.00 | null |
---- -------------------- ------- ------------ ------ --------------------------- -------------------- --------- ------------------------ ------ ---------- -------------
5 rows in set, 2 warnings (0.00 sec)
并且,mysql工作台生成了以下可视化执行计划:
对于经验丰富的人来说,表格执行计划可以识别出性能更好的查询,但是可视化执行计划更适合sql调优新手。
第二个查询性能最好,因为它通过最好地利用索引读取最少的数据。 和往常一样,我希望这些例子能够帮助那些希望学习更多关于mysql的知识的人。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。