报表分页实现你是不是这样做?
图 1对应 SQL 如下:
show session status like '%handl%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 10 |
| Handler_read_key | 21 |
| Handler_read_last | 0 |
| Handler_read_next | 322 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 12 |
| Handler_read_rnd_next | 101 |
+-----------------------+-------+
7 rows in set (0.00 sec)
select count(*) cnt from mysql.help_topic where help_topic_id<100;
-- 假如默认一页显示 20 行
select * from mysql.help_topic where help_topic_id<100 limit 20;
show session status like '%handl%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 12 |
| Handler_read_key | 23 |
| Handler_read_last | 0 |
| Handler_read_next | 441 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 12 |
| Handler_read_rnd_next | 101 |
+-----------------------+-------+
7 rows in set (0.00 sec)
read 开销:
- Handler_read_first:2
- Handler_read_key:2
- Handler_read_next:119
被误以为的利器:SQL_CALC_FOUND_ROWS
show session status like '%handl%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 12 |
| Handler_read_key | 23 |
| Handler_read_last | 0 |
| Handler_read_next | 441 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 12 |
| Handler_read_rnd_next | 101 |
+-----------------------+-------+
7 rows in set (0.01 sec)
select SQL_CALC_FOUND_ROWS *
from mysql.help_topic
where help_topic_id<100 limit 20;
select found_rows();
+--------------+
| found_rows() |
+--------------+
| 100 |
+--------------+
1 row in set (0.00 sec)
show session status like '%handl%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 13 |
| Handler_read_key | 24 |
| Handler_read_last | 0 |
| Handler_read_next | 541 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 12 |
| Handler_read_rnd_next | 101 |
+-----------------------+-------+
7 rows in set (0.00 sec)
read 开销:
- Handler_read_first:1
- Handler_read_key:1
- Handler_read_next:100
官方将砍掉 SQL_CALC_FOUND_ROWS
图 2总结
- 部分场景下使用 SQL_CALC_FOUND_ROWS 确实可以获得不错的性能提升,避免不必要的读取操作。
- SQL_CALC_FOUND_ROWS 在 8.0 中标识将废弃。
- SQL_CALC_FOUND_ROWS 在部分查询场景下可能获取非预期的值。
禁止使用 SQL_CALC_FOUND_ROWS hint,而是使用 count(*) 来计算页数。
关于我
来源:简书 - linora
作者:EZy-1990(ixdba/linora)
关于作者:DBA 一枚,09 年开始接触数据库。早年间从事 Oracle DBA 一职,目前专注于开源数据库领域,混过很多家公司,玩过多种数据库。
其他说明:不能保证全文没有任何不妥之处,如有发现,不吝赐教。
🙊🙊🙊🙊🙊🙊🙊
网友评论