清除 MySQL 缓存
Clear MySQL Cache
我接手了一个用Laravel 4写的项目。我们有 MySQL 5.6.21 - PHP 5.4.30 - 目前 运行 正在 Windows 8.1.
每天早上第一次尝试访问着陆页时 - 该页面在后端包含大约 5 个查询 - 该网站将因 php 超时(超过 30 秒的响应)而崩溃。
使用以下方法后,我更接近原因:Laravel 4 - logging SQL queries。其中一个查询在第一次调用时花费的时间超过 25 秒。之后总是 < 0.5 秒。
查询有 3 个连接和 2 个子选择包含在 Cache::remember 中。我想对此进行优化,以便在生产中不会 运行 出现此问题。
所以我想测试不同的SQLs
问题是第一次以某种方式缓存数据,然后我看不到我的新 SQL 是否更好。
现在,因为我猜这是一个缓存问题(第一次尝试需要很长时间,之后就不会了)我做了这些:
MySQL: FLUSH TABLES;
restart MySQL
restart Apache
php artisan cache:clear
但是,查询仍然很快。然后一段时间后我根本不访问数据库(无法给出确切时间,可能是 4 小时不活动)它再次发生。
解释说:
1 | Primary | table1 | ALL | 2 possible keys | NULL | ... | 1010000 | using where; using temporary; using filesort
1 | Primary | table2 | eq_ref | PRIMARY | PRIMARY | ... | 1 | using where; using index
1 | Primary | table3 | eq_ref | PRIMARY | PRIMARY | ... | 1 | using where; using index
1 | Primary | table4 | eq_ref | PRIMARY | PRIMARY | ... | 1 | NULL
3 | Dependent Subquery | table5 | ref | 2 possible keys | table1.id | ... | 17 | using where
2 | Dependent Subquery | table5 | ref | 2 possible keys | table1.id | ... | 17 | using where
下面是问题:
- 这么长的时间是什么原因?
- 我怎样才能重现它?和
- 有办法解决吗?
我读了mysql slow on first query, then fast for related queries。但是,这并没有回答我关于如何重现此行为的问题。
更新
我修改了SQL,现在写成这样:
select
count(ec.id) as asdasda
from table1 ec force index for join (PRIMARY)
left join table2 e force index for join (PRIMARY) on ec.id = e.id
left join table3 v force index for join (PRIMARY) on e.id = v.id
where
v.col1 = 'aaa'
and v.col2 = 'bbb'
and v.col3 = 'ccc'
and e.datecol > curdate()
and e.col1 != 0
现在解释说:
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
| 1 | SIMPLE | table3 | ALL | PRIMARY | NULL | NULL | NULL | 114032 | Using where |
| 1 | SIMPLE | table2 | ref | PRIMARY | PRIMARY | 5 | table3.id | 11 | Using where |
| 1 | SIMPLE | table1 | eq_ref | PRIMARY | PRIMARY | 4 | table2.id | 1 | Using index |
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
这是最好的了吗?
数据可能缓存在 InnoDB 缓冲池或 Windows 文件系统缓存中。
您不能显式刷新 InnoDB 缓存,但您可以将刷新参数设置为更激进的值:
SET GLOBAL innodb_old_blocks_pct = 5
SET GLOBAL innodb_max_dirty_pages_pct = 0
您可以使用此处提供的解决方案来清除 Windows 文件系统缓存:Clear file cache to repeat performance testing
但您真正需要的是 table3 (col1, col2, col3)
上的索引
我接手了一个用Laravel 4写的项目。我们有 MySQL 5.6.21 - PHP 5.4.30 - 目前 运行 正在 Windows 8.1.
每天早上第一次尝试访问着陆页时 - 该页面在后端包含大约 5 个查询 - 该网站将因 php 超时(超过 30 秒的响应)而崩溃。
使用以下方法后,我更接近原因:Laravel 4 - logging SQL queries。其中一个查询在第一次调用时花费的时间超过 25 秒。之后总是 < 0.5 秒。
查询有 3 个连接和 2 个子选择包含在 Cache::remember 中。我想对此进行优化,以便在生产中不会 运行 出现此问题。
所以我想测试不同的SQLs 问题是第一次以某种方式缓存数据,然后我看不到我的新 SQL 是否更好。
现在,因为我猜这是一个缓存问题(第一次尝试需要很长时间,之后就不会了)我做了这些:
MySQL: FLUSH TABLES;
restart MySQL
restart Apache
php artisan cache:clear
但是,查询仍然很快。然后一段时间后我根本不访问数据库(无法给出确切时间,可能是 4 小时不活动)它再次发生。
解释说:
1 | Primary | table1 | ALL | 2 possible keys | NULL | ... | 1010000 | using where; using temporary; using filesort
1 | Primary | table2 | eq_ref | PRIMARY | PRIMARY | ... | 1 | using where; using index
1 | Primary | table3 | eq_ref | PRIMARY | PRIMARY | ... | 1 | using where; using index
1 | Primary | table4 | eq_ref | PRIMARY | PRIMARY | ... | 1 | NULL
3 | Dependent Subquery | table5 | ref | 2 possible keys | table1.id | ... | 17 | using where
2 | Dependent Subquery | table5 | ref | 2 possible keys | table1.id | ... | 17 | using where
下面是问题:
- 这么长的时间是什么原因?
- 我怎样才能重现它?和
- 有办法解决吗?
我读了mysql slow on first query, then fast for related queries。但是,这并没有回答我关于如何重现此行为的问题。
更新
我修改了SQL,现在写成这样:
select
count(ec.id) as asdasda
from table1 ec force index for join (PRIMARY)
left join table2 e force index for join (PRIMARY) on ec.id = e.id
left join table3 v force index for join (PRIMARY) on e.id = v.id
where
v.col1 = 'aaa'
and v.col2 = 'bbb'
and v.col3 = 'ccc'
and e.datecol > curdate()
and e.col1 != 0
现在解释说:
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
| 1 | SIMPLE | table3 | ALL | PRIMARY | NULL | NULL | NULL | 114032 | Using where |
| 1 | SIMPLE | table2 | ref | PRIMARY | PRIMARY | 5 | table3.id | 11 | Using where |
| 1 | SIMPLE | table1 | eq_ref | PRIMARY | PRIMARY | 4 | table2.id | 1 | Using index |
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+
这是最好的了吗?
数据可能缓存在 InnoDB 缓冲池或 Windows 文件系统缓存中。
您不能显式刷新 InnoDB 缓存,但您可以将刷新参数设置为更激进的值:
SET GLOBAL innodb_old_blocks_pct = 5
SET GLOBAL innodb_max_dirty_pages_pct = 0
您可以使用此处提供的解决方案来清除 Windows 文件系统缓存:Clear file cache to repeat performance testing
但您真正需要的是 table3 (col1, col2, col3)