mysql 与文件系统缓存

MyISAM表的缓存

(网上复制粘贴的,其实我认为这不是mysql的缓存,而是文件系统的,不过赞分析方法)

前言:

今天一个朋友问了一个问题,原文如下:mysql5.1,myisam的表,select count(*) as total FROM m_bff WHERE from_uid=‘73149293‘ AND isdeleted=0。from_uid上有索引,第一次执行这个句子速度慢,1秒多,用show profile看都慢在Sending data上。但是紧接着我加上sql_no_cache,执行只需要0.01秒了,有好多句子都是类似的情况第一次慢,后来加上sql_no_cache也不慢,Key_blocks_unused也很多,请教下这种是什么原因呢?

问题总结一下就是:对于MyISAM表的查询,为何第一次会比第二次慢非常多?

回想innodb和MyISAM的区别,其中非常重要的一个就是MyISAM只缓存索引内容,而innodb不仅缓存索引还缓存数据。那照理说MyISAM每次的数据查询都应该是Disk Access不会有很大的速度差距吧。

其实在MyISAM的文件和操作系统之间还有一层OS级别的文件缓存。猜测就是OS文件缓存捣的鬼。

验证:

验证方式其实很简单,在shell下以root权限运行 cat 3 > /proc/sys/vm/drop_caches 把OS的文件缓存清空,再运行SQL看看是不是和第一次运行的速度一样就可以知道了。

结果:

恩,echo 3 /proc/sys/vm/drop_caches 之后就又慢了,看来就是你说的问题了

引申:

知道了MyISAM这个特性后,可以用文件预读的方法来做数据预热。

假设某个表是热点表,且操作系统又有较多的内存空余。我们可以用cat table.MYD >> /dev/null 的方式来把文件加载到OS文件缓存中。这样当某些用户的数据第一次访问时就不会出现慢查询了

时间: 2024-10-18 16:50:08

mysql 与文件系统缓存的相关文章

mysql查看查询缓存是否启用

查看查询缓存情况: mysql> show variables like '%query_cache%'; (query_cache_type 为 ON 表示已经开启) +------------------------------+----------+ | Variable_name                | Value    | +------------------------------+----------+ | have_query_cache             |

用Redis作为Mysql数据库的缓存【转】

用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按表存储的:更微观地看,这些表都是按行存储的.每执行一次select查询,Mysql都会返回一个结果集,这个结果集由若干行组成.所以,一个自然而然的想法就是在Redis中找到一种对应于Mysql行的数据结构.Redis中提供了五种基本数据结构,即字符串(string).列表(list).哈希(has

MySQL的查询缓存功能现已成了瓶颈!

如果你在网上搜索一下"tuning MySQL query cache"(优化MySQL查询缓存),看到那么多的结果以及有人提供的五花八门的建议,这则新闻也就并不完全令人惊讶了. 正如MySQL Server的产品经理摩根·托克(Morgan Tocker)在这里撰写的那样,问题在于可扩展性. 缓存的操作看起来简单得很:SELECT(选择)命令存储在一个哈希表(又叫散列表,hash table)中:如果入站请求与哈希匹配,服务器就能返回上一次查询执行的结果(并且有保护机制,那样服务器不

MySQL ·InnoDB 文件系统之文件物理结构

从上层的角度来看,InnoDB层的文件,除了redo日志外,基本上具有相当统一的结构,都是固定block大小,普遍使用的btree结构来管理数据.只是针对不同的block的应用场景会分配不同的页类型.通常默认情况下,每个block的大小为 UNIV_PAGE_SIZE,在不做任何配置时值为16kb,你还可以选择在安装实例时指定一个块的block大小.对于压缩表,可以在建表时指定block size,但在内存中表现的解压页依旧为统一的页大小. 从物理文件的分类来看,有日志文件.主系统表空间文件ib

初学Redis(2)——用Redis作为Mysql数据库的缓存

用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按表存储的:更微观地看,这些表都是按行存储的.每执行一次select查询,Mysql都会返回一个结果集,这个结果集由若干行组成.所以,一个自然而然的想法就是在Redis中找到一种对应于Mysql行的数据结构.Redis中提供了五种基本数据结构,即字符串(string).列表(list).哈希(has

《MySQL与Redis缓存架构》

<如何使用redis做mysql的缓存> 应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql. 同时要注意避免冲突,在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增并进行读取,若mysql更新失败,则需要及时清除缓存及同步redis主键. 这样处理,主要是实时读写redis,而mysql数据则通过队列异步处理,缓解mysql压力,不过这种方法应用场景主要基于高并发,而且redis的高可用集群架构相对更复杂,一般不是很

初学Redis(3)——用Redis作为Mysql数据库的缓存

把Mysql结果集缓存到Redis的字符串或哈希结构中以后,我们面临一个新的问题,即如何为这些字符串或哈希命名,也就是如何确定它们的键.因为这些数据结构所对应的行都属于某个结果集,假如可以找到一种唯一标识结果集的方法,那么只需为这些数据结构分配一个唯一的序号,然后把结果集标识符与该序号结合起来,就能唯一标识一个数据结构了.于是,为字符串和哈希命名的问题就转化为确定结果集标识符的问题. 经过调研,发现一种较为通用的确定结果集标识符的方法.正如我们所知道的,缓存在Redis中的结果集数据都是利用se

MySQL最大连接数/缓存设置

一.最大连接数: 1.查看当前数据库的最大连接数:SHOW VARIABLES LIKE '%max_connections%'; 2.设置数据库的最大连接数: 1)在当前会话中设,数据库重启之后失效: SET GLOBAL max_connections = 1000; 2)在数据库的配置文件my.ini里设,长期有效: max_connections=151 二.缓存: 1.开启:在my.ini中的[mysqld]中加入以下: query_cache_size = 32M query_cac

用Redis作为Mysql数据库的缓存

看到一篇不错的博文,记录下: http://blog.csdn.net/qtyl1988/article/details/39553339 http://blog.csdn.net/qtyl1988/article/details/39519951 http://blog.csdn.net/qtyl1988/article/details/39524713 http://blog.csdn.net/qtyl1988/article/details/39545531 该文是采用C++写的,PHP的