Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18243
  • 博文数量: 22
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-18 10:33
文章分类
文章存档

2015年(22)

我的朋友

分类: Mysql/postgreSQL

2015-03-01 11:54:41

    查询缓存中存储一个SELECT语句的结果,连同相应的文本发送到客户端。如果收到一个相同的声明后,从服务器检索查询缓存而不是再次解析和执行语句的结果。查询缓存共享会话,一个客户端可以响应于由另一个客户端发出同样的查询发送的同一个结果集。

    查询缓存可以处理经常收到需要相同查询但不经常改变的表,这是许多Web服务器生成基于数据库的动态网页内容的许多典型的情况。

    查询缓存不返回的数据。当表被修改,与查询缓存任何相关的条目被刷新。

    为查询缓存的一些性能数据如下。
  • 如果所有的查询执行很简单,但还是有所不同这样的查询不能被缓存,为查询缓存活动的开销是13%。这可能被视为最坏的情况下。

  • 搜索在单行表中的一行与查询缓存比没有它快238%。这可以被视为接近可以预期的查询缓存最小的加速比。

    禁止在服务器启动查询缓存,设置query_cache_size系统变量为0。通过禁用查询缓存的代码,没有明显的开销。

    查询缓存提供了显着的性能改善的潜力,但不要以为这会在任何情况下都会改善性能。一些查询缓存的配置或服务器的负载,会看到一个性能下降:
  • 小心尺寸过大的查询缓存。
  • 服务器的工作负载对查询缓存效率有显著影响。查询结构几乎全部由一套固定的SELECT语句的更可能从启用缓存比混合在其中频繁的INSERT语句导致结果的不断失效缓存中受益。在某些情况下,一种解决方法是使用SQL_NO_CACHE选项,以防止甚至进入了高速缓存对于使用频繁修改的表的SELECT语句的结果。

8.9.3.1. How the Query Cache Operates(查询缓存如何工作)

    传入查询相比那些在查询缓存中在解析之前, 所以下面的两个查询被视为由不同的查询缓存:
SELECT * FROM tbl_name
Select * from tbl_name

    查询必须是完全相同的(逐字节)被视为是相同的。使用不同的数据库查询,不同的 协议版本,或者不同的默认字符集被认为是不同的查询,并分别缓存。

    高速缓存不用于以下类型的查询:

  • 查询是一个外部查询的子查询

  • 查询所存储的函数,触发器或事件的主体内执行
    
    前一个查询的结果是从查询缓存中提取,MySQL检查用户是否有SELECT权限所涉及的所有数据库和表。如果不是这种情况下,不使用高速缓存的结果

    如果查询结果从查询缓存中返回,服务器递增Qcache_hits的[631]状态变量,而不是Com_select。详见,Section 8.9.3.4, “Query Cache Status and Maintenance”。

    如果表变化,使用该表中的所有缓存的查询变得无效,并从缓存中删除。这包括使用MERGE映射到改变后的表的表查询。一个表可以被许多类型的语句改变,如INSERT,UPDATE,DELETE,TRUNCATE TABLE,ALTER TABLE,DROP TABLE或DROP DATABASE。

    查询缓存也在事务中工作当使用InnoDB表时。

    在MySQL5.6,从视图中的SELECT查询的结果被缓存。

    查询缓存适用于SELECT SQL_CALC_FOUND_ROWS...查询和存储是由以下SELECT FOUND_ROWS()查询返回的值。FOUND_ROWS()[1342]返回即使前述查询是从缓存中取出,因为发现的行数也被存储在高速缓存中的正确的值。在SELECT FOUND_ROWS()查询本身不能被缓存。

    如果它包含任何如下表所示功能的查询不能被缓存。


    查询也没有缓存在这些条件下:

  • 它指的是用户定义的函数(UDF)或存储功能。

  • 它是指用户变量或局部存储程序变量。

  • 它是指在mysql,INFORMATION_SCHEMA或performance_schema数据库表。

  • (MySQL 5.6.5和以后:)它是指任何分区表。

  • 它是以下任何形式:
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT * FROM ... WHERE autoincrement_col IS NULL
最后的形式不被缓存因为它被用作ODBC解决方法用于获得最后的插入ID值。Connector/ODBC详见 Chapter 21, Connectors and APIs。

使用SERIALIZABLE[1555]隔离级别也事务中的语句不能被缓存,因为他们使用LOCK IN SHARE MODE锁。

  • 它使用临时表

  • 它不使用任何表。

  • 它产生的警告。

  • 用户具有列级权限为任何所涉及的表。

8.9.3.2.查询缓存选择选项(Query Cache SELECT Options)

    两个查询缓存相关的选项可以指定在SELECT语句:
  • SQL_CACHE
    查询结果被缓存,如果它是可缓存和query_cache_type的系统变量的值是ONDEMAND

  • SQL_NO_CACHE
    服务器不使用查询缓存。它不检查查询缓存,看看结果是否已经被缓存,也没有缓存的查询结果。

8.9.3.3.查询缓存配置(Query Cache Configuration)
    通过have_query_cache服务器系统变量指示查询缓存是否可用:
        mysql> SHOW VARIABLES LIKE 'have_query_cache';
        +------------------+-------+
        | Variable_name | Value |
        +------------------+-------+
        | have_query_cache | YES |
        +------------------+-------+

    当使用标准的MySQL二进制,此值始终YES,即使查询缓存被禁用。

    其他几个系统变量控制查询缓存操作。这些可以在启动mysqld时在选项文件或命令行中进行设置。查询缓存系统变量都有了名以query_cache_开头。这些变量,详见,Section 5.1.4, “Server System Variables”。

    通过设置query_cache_size变量系统变量控制查询缓存的大小。将其设置为0禁用查询缓存,如query_cache_type=0。默认情况下,查询缓存被禁用。当query_cache_type=0,使用1M的缓存。

    为了显著减少开销,也启动服务器,query_cache_type的=0[560]如果你不会使用查询缓存。

    当设置query_cache_size变量[559]为非零值,请记住,查询缓存需要大约40KB来分配其结构的最小尺寸。(精确大小取决于系统架构。)如果您设置的值太小,你会得到一个警告,如本例:
mysql> SET GLOBAL query_cache_size = 40000;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1282
Message: Query cache failed to set size 39936;
new query cache size is 0
mysql> SET GLOBAL query_cache_size = 41984;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| query_cache_size | 41984 |
+------------------+-------+

    对于查询缓存居然能容纳任何查询结果,它的大小必须设置较大:
mysql> SET GLOBAL query_cache_size = 1000000;
Query OK, 0 rows affected (0.04 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| query_cache_size | 999424 |
+------------------+--------+
1 row in set (0.00 sec)

    该query_cache_size[559]变量的值被对准到最接近1024字节块。因此,报告的值可能与您分配的值不同。

    如果查询缓存大小大于0,则query_cache_type[560]变量的影响它是如何工作的。此变量可以被设置为以下值:

  • 0或OFF值将阻止缓存或缓存结果的检索。

  • 1或ON的值使缓存那些以SELECT SQL_NO_CACHE语句的除外。

  • 2或需求值导致只有那些以SELECT SQL_CACHE语句缓存。

    如果query_cache_size[559]变量为0,你还应该设置query_cache_type的[560]变量为0。在这种情况下,服务器不获取查询缓存互斥在所有,这意味着该查询缓存不能在运行时使能并且减少开销在查询执行。


8.9.3.4. Query Cache Status and Maintenance(查询缓存状态和维护)
    
    要检查查询缓存是否存在于你的MySQL服务器,使用下面的语句:
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+

    你可以整理查询缓存,以更好地利用其内存用FLUSH QUERY CACHE语句。该语句不从缓存中删除任何疑问。

    该RESET QUERY CACHE语句从查询缓存中的所有查询结果。该FLUSH TABLES语句也这样做了。

    为了监视查询缓存性能,使用SHOW STATUS查看缓存状态变量:
mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+--------+
| Variable_name | Value |
+-------------------------+--------+
| Qcache_free_blocks | 36 |
| Qcache_free_memory | 138488 |
| Qcache_hits | 79570 |
| Qcache_inserts | 27087 |
| Qcache_lowmem_prunes | 3114 |
| Qcache_not_cached | 22989 |
| Qcache_queries_in_cache | 415 |
| Qcache_total_blocks | 912 |
+-------------------------+--------+

    这些变量的说明中给出了Section 5.1.6, “Server Status Variables”。某些用途为他们在此说明。

    SELECT查询的总数由下式给出以下公式:
    Com_select
+ Qcache_hits
+ queries with errors found by parser

    该Com_select值由下式给出这个公式:
    Qcache_inserts
+ Qcache_not_cached
+ queries with errors found during the column-privileges check

    查询缓存使用长度可变块,因此Qcache_total_blocks[631]和 Qcache_free_blocks[631]可显示查询缓存内存碎片。经过FLUSH QUERY CACHE,只有一个空闲块仍然存在。

    每个缓存的查询至少需要两个块(一个用于查询文本和一个或多个用于查询的结果)。另外,所使用的查询表的每需要一个块。然而,如果两个或多个查询使用相同的表,仅一个表块需要分配。

    由Qcache_lowmem_prunes提供的信息[631]的状态变量可以帮助你调整查询缓存的大小。据计算已经从缓存中删除以释放内存缓存的新查询的查询数量。查询缓存使用最近最少使用(LRU)策略来确定哪些查询从缓存中删除。调整信息见Section 8.9.3.3, “Query Cache  Configuration”。

















































    
阅读(250) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~