[1] 查询缓存
MySQL的缓存机制简单地说就是缓存SQL语句和查询的结果,如果运行相同的SQL语句,服务器会直接从缓存中取到结果,而不需要再去解析和执行SQL语句。
查询缓存会存储最新数据,而不会返回过期数据。当数据被修改后,在查询缓存中的任何相关数据均被清除。
查询缓存会存储最新数据,而不会返回过期数据。当数据被修改后,在查询缓存中的任何相关数据均被清除。
1.1 重要变量
输入以下命令进行查看:
show variables like '%query_cache%';
· have_query_cache
用来设置是否支持查询缓存区,“YES”表示支持查询缓存区。
· query_cache_limit
用来设置 MySQL 可以缓存的最大结果集,大于此值的结果集不会被缓存,该参数默认值是1MB.
· query_cache_min_res_unit
用来设置分配内存块的最小体积,每次给查询缓存结果分配内存的大小,默认分配4096个字节,如果此值较小,那么会节省内存,但是这样会使系统频繁分配内存块。
· query_cache_size
用来设置查询缓存使用的总内存字节数,必须是1024字节的倍数。
· query_cache_type
用来设置是否启用查询缓存。如果设置为OFF,表示不进行缓存;如果设置为ON,表示除了SOL NO_CACHE的查询以外,缓存所有的结果;如果设置为DEMAND,表示仅缓存SQL_CACHE的查询。
· query_cache_type
用来设置是否启用查询缓存。如果设置为OFF,表示不进行缓存;如果设置为ON,表示除了SOL NO_CACHE的查询以外,缓存所有的结果;如果设置为DEMAND,表示仅缓存SQL_CACHE的查询。
1.2 相关知识
1、查询缓存不会缓存引用了用户自定义函数、存储函数、用户自定义变量、临时表的查询。
2、查询缓存只是发生在服务器第一次接收到SOL查询语句,然后把查询结果缓存起来,对于查询中的子查询、视图查询和存储过程查询都不能缓存结果,对于预存储语句同样也不能使用缓存。
3、使用查询缓存有利也有弊。一方面,查询缓存可以使查询变得更加高效,改善了MySQL服务器的性能;另一方面,查询缓存本身也需要消耗系统IO资源,所以说,查询缓存也增加了服务器额外的开销,主要体现以下几个方面:
3.1、MySQL服务器在进行查询之前首先会检测查询缓存是否存在相同的查询条目。
3.2、MySQL服务器在进行查询操作时,如果缓存中没有相同的查询条目,会将查询的结果缓存到查询缓存,这个过程也需要开销系统资源。
3.3、如果数据库表发生增加操作,MySQL服务器查询缓存中相对应的查询结果将会无效,这时同样需要消耗系统资源.
4、除了注意以上问题可以提高查询缓存的命中率外,还可以通过分区表提高缓存的命中率。通常我们会遇到这样的问题,对于某张表某个时间段内的数据更新比较频繁,其他时间段查询和更新比较多,一旦数据表数据执行更新操作,那么查询缓存中的信息将会清空,查询级存的命中率不会很高。此时,可以考虑采用分区表,把某个时间段的数据存放在一个单独的分区表中,这样可以提高服务器的查询缓存的命中率。
[2] 合并表、分区表
2.1 合并表
合并表相当于一个容器,里面包含了多个真实表。
合并表(merge table)是一种早期的、简单的分区实现,和分区表相比有一些不同的限制,并且缺乏优化。分区表严格来说是一个逻辑上的概念,用户无法访问底层的各个分区,对用户来说分区是透明的。但是合并表允许用户单独访问各个子表。分区表和优化器的结合更紧密,这也是未来发展的趋势,而合并表则是一种将被淘汰的技术,在未来的版本中可能被删除。
2.2 分区表
对用户来讲,分区表示一个独立的逻辑表,但是底层由多个物理子表组成。在底层系统来看,每个分区表都有一个使用#分割命名的表文件。
分区表的目的:让某些特定查询减少相应时间; 在下列的场景中,分区可以起到非常大的作用:
1. 表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。
2. 分区表的数据更容易维护。例如,想批量删除大量数据可以使用清除整个分区的方式。另外,还可以对一个独立分区进行优化、检查、修复等操作。
3. 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
4. 可以使用分区表来避免某些特殊的瓶颈。例如:InnoDB的单个索引的互斥访问、ext3文件系统的inode锁竞争等。
5. 如需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好。
假设我们要在一个非常大的表中查出一段时间的记录,这个表含有很多年的历史数据,而我们要查询的仅仅是最近几个月的数据,这大约有10亿条记录。使用全表扫描,那么速度肯定会很慢,使用索引会在空间和维护上有很大消耗,最终一个查询会有产生成千上万的随机I/O,应用程序就会因此僵死。
所以这里我们使用分区表来解决这个问题。为了保证大数据的可拓展性,一般有下面两个策略:
全量扫描数据,不要任何索引。使用简单的分区方式存放表,不要任何索引。
索引数据,并分离热点。如果数据有明显的‘热点’,而且除了这部分数据,其他数据很少被访问到,那么可以将这部分热点数据单独放在这个分区中,让这个分区的数据能够有机会都缓存在内存中。这样查询就可以只访问一个很小的分区表,能够使用索引,也能够有效地使用缓存。