SQL查询优化分析(900W+数据,从17s到300ms)( 二 )
InnoDB中有buffer pool 。 里面存有最近访问过的数据页 , 包括数据页和索引页 。 所以我们需要运行两个sql , 来比较buffer pool中的数据页的数量 。 预测结果是运行select * from test a inner join (select id from test where val=4 limit 300000,5); 之后 , buffer pool中的数据页的数量远远少于select * from test where val=4 limit 300000,5;对应的数量 , 因为前一个sql只访问5次数据页 , 而后一个sql访问300005次数据页 。
select * from test where val=4 limit 300000,5
mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('val','primary') and TABLE_NAME like '%test%' group by index_name;Empty set (0.04 sec)
可以看出 , 目前buffer pool中没有关于test表的数据页 。
mysql> select * from test where val=4 limit 300000,5;+---------+-----+--------+| id| val | source |+---------+-----+--------+| 3327622 |4 |4 || 3327632 |4 |4 || 3327642 |4 |4 || 3327652 |4 |4 || 3327662 |4 |4 |+---------+-----+--------+5 rows in set (26.19 sec) mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('val','primary') and TABLE_NAME like '%test%' group by index_name;+------------+----------+| index_name | count(*) |+------------+----------+| PRIMARY|4098 || val|208 |+------------+----------+2 rows in set (0.04 sec)
可以看出 , 此时buffer pool中关于test表有4098个数据页 , 208个索引页 。
select * from test a inner join (select id from test where val=4 limit 300000,5) ;为了防止上次试验的影响 , 我们需要清空buffer pool , 重启mysql 。
mysqladmin shutdown/usr/local/bin/mysqld_safeEmpty set (0.03 sec)
运行sql:
mysql> select * from test a inner join (select id from test where val=4 limit 300000,5) b on a.id=b.id;+---------+-----+--------+---------+| id| val | source | id|+---------+-----+--------+---------+| 3327622 |4 |4 | 3327622 || 3327632 |4 |4 | 3327632 || 3327642 |4 |4 | 3327642 || 3327652 |4 |4 | 3327652 || 3327662 |4 |4 | 3327662 |+---------+-----+--------+---------+5 rows in set (0.09 sec) mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('val','primary') and TABLE_NAME like '%test%' group by index_name;+------------+----------+| index_name | count(*) |+------------+----------+| PRIMARY|5 || val|390 |+------------+----------+2 rows in set (0.03 sec)
我们可以看明显的看出两者的差别:第一个sql加载了4098个数据页到buffer pool , 而第二个sql只加载了5个数据页到buffer pool 。 符合我们的预测 。 也证实了为什么第一个sql会慢:读取大量的无用数据行(300000) , 最后却抛弃掉 。
而且这会造成一个问题:加载了很多热点不是很高的数据页到buffer pool , 会造成buffer pool的污染 , 占用buffer pool的空间 。 遇到的问题
【SQL查询优化分析(900W+数据,从17s到300ms)】为了在每次重启时确保清空buffer pool , 我们需要关闭innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup , 这两个选项能够控制数据库关闭时dump出buffer pool中的数据和在数据库开启时载入在磁盘上备份buffer pool的数据 。
- 安全漏洞大揭秘:手把手教你轻松防止SQL注入
- 芯片应用如何助力北京高端制造业产业优化?
- 《深入理解Java虚拟机》:锁优化
- 网站优化教程有哪些重点方面?
- seo优化的网站日志分析
- 全站优化要想做好,seo要做好什么?
- 快速入门ElasticSearch(下)
- 网站优化有哪些逆向思维方式?
- 腾讯面试:MySQL事务与MVCC如何实现的隔离级别?
- 图解|什么是高并发利器NoSQL