清除MySQL缓存

时间:2015-06-25 17:08:59

标签: mysql query-performance

我接手了一个用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 中。我想进行优化,以便在生产中不会遇到这个问题。

所以我想测试不同的SQL 问题是第一次以某种方式缓存数据然后我无法查看我的新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 |
+----+-------------+--------+--------+---------------+--------------+---------+-----------------+--------+-------------+

这样可以获得最好的效果吗?

1 个答案:

答案 0 :(得分:0)

数据可能会缓存在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)

上的索引