📄 06-9.html
字号:
<HTML>
<HEAD>
<TITLE>MySQL 4.1.0 中文参考手册 --- 犬犬(心帆)翻译</TITLE>
<style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
<META http-equiv="Content-Type" content="text/html; charset=gb2312">
<META name="description" content="MySQL 4.1.0 中文参考手册">
<META name="keywords" content="MySQL,4.1.0,Shuixin13,MySQL 4.1.0,中文,中文参考手册,犬犬(心帆)">
<LINK rel="shortcut icon" href="shuixin13.ico" />
<LINK href="images/index.css" type=text/css rel=STYLESHEET>
<SCRIPT language=javascript src="images/index.js"></SCRIPT>
<SCRIPT language=javascript><!--
x = new Date()
function cal() {
y = new Date()
diff = y.getTime() - x.getTime()
document.write("载入时间 " + diff/1000 + " 秒")
}
//--></SCRIPT>
<SCRIPT language=JavaScript>
var currentpos,timer;
function initialize()
{
timer=setInterval("scrollwindow()",10);
}
function sc()
{
clearInterval(timer);
}
function scrollwindow()
{
currentpos=document.body.scrollTop;
window.scroll(0,++currentpos);
if (currentpos != document.body.scrollTop)
sc();
}
document.onmousedown=sc
document.ondblclick=initialize
</SCRIPT>
</HEAD>
<BODY BGCOLOR=#efefff TEXT=#000000 LINK=#101090 VLINK=#7030B0>
<H1>MySQL Reference Manual for version 4.1.0-alpha.</H1>
<P>
<P><HR>
<H2><a name="Query_Cache"></a>6.9 MySQL 查询缓存</H2>
<p> <a name="IDX1517"></a> <a name="IDX1518"></a> </p>
<p> 从 MySQL 4.0.1 开始,<code>MySQL server</code> 有一个重要的特征:<code>Query Cache</code>。
当在使用中,查询缓存会存储一个 <code>SELECT</code> 查询的文本与被传送到客户端的相应结果。如果之后接收到一个同样的查询,服务器将从查询缓存中检索结果,而不是再次分析和执行这个同样的查询。
</p>
<p> <strong>注意:</strong>查询缓存绝不返回过期数据。当数据被修改后,在查询缓存中的任何相关词条均被转储清除。 </p>
<p> 在某些表并不经常更改,而你又对它执行大量的相同查询时,查询缓存将是非常有用的。对于许多 WEB 服务器使用大量的动态信息,这是一个很典型的情况。 </p>
<p> 下面是查询缓存的一个性能数据。(这些结果的产生,是通过在一个 a Linux Alpha 2 x 500 MHz、2GB RAM 和 64MB 查询缓存上执行
MySQL 基准套件和到的): </p>
<ul>
<li> 如果你执行的所有查询均是简单的(比如从表中一行一行的选取);但是仍然是不同的,所以该查询不能被缓冲,查询缓存处于活动时,开销为 13%。这可以被看作是最差的情况。然而,在实际情况下,查询是比我们的简单示例要复杂得多的,所以开销通常显著得低。
<li> 在只有一行记录表中搜索一行后,搜索将快 238% 。这可以被认为是接近于对一个被缓冲的查询所期望的最小的加速。
<li> 如果你希望禁用查询缓存,设置 <code>query_cache_size=0</code>。禁用了查询缓存,将没有明显的开销。(在配置选项
<code>--without-query-cache</code> 的帮助下,查询缓存可以被排除在外码之外)
</ul>
<h3>6.9.1 查询缓存如何运作</h3>
<a name="Query_Cache_How"></a>
<p> 查询在分析之前先被比较,因而 </p>
<pre>
SELECT * FROM tbl_name
</pre>
<p> 和 </p>
<pre>
Select * from tbl_name
</pre>
<p> 对于查询缓存被当作是不同的查询,因而查询需要严格的一致(字节对字节的),才会被认为是同样的。 另外,如果一个客户端使用一个新的连接协议格式或不同于其它客户端的另一个字符集,一个查询将被视为不同的。
</p>
<p> 使用不同数据库的,使用不同协议版本的,或使用不同的缺省字符串的查询将被认为是不同的查询,并将分别的缓冲。 </p>
<p> 高速缓冲不对 <code>SELECT CALC_ROWS ...</code> 和 <code>SELECT FOUND_ROWS() ...</code>
类型的查询起作用,因为找到的行的数目也是被存储在缓冲里的。 </p>
<p> 如果查询结果被从查询缓存中返回,那么状态变量 <code>Com_select</code> 将不会被增加,但是 <code>Qcache_hits</code>
却会增加。查看章节 <a href="06-9.html#Query_Cache_Status_and_Maintenance">6.9.4 查询缓存的状态和维护</a>。
</p>
<p> 如果一个表发生的改变 (<code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>,
<code>TRUNCATE</code>, <code>ALTER</code> 或 <code>DROP TABLE|DATABASE</code>),那么所有这张表使用的缓冲的查询(可能通过一个
<code>MRG_MyISAM</code> 表!)将被得失效,并从缓冲中移除。 </p>
<p> <code>InnoDB</code> 表的事务所做的更改将在一个 <code>COMMIT</code> 被完成时,使数据失效。 </p>
<p> 如果一个查询包括下面的函数,它将不能被缓冲:
<table BORDER width="95%">
<tr>
<td><strong>函数 </strong> </td>
<td> <strong>函数 </strong> </td>
<td> <strong>函数 </strong> </td>
</tr>
<tr>
<td><code>User-Defined Functions</code> </td>
<td> <code>CONNECTION_ID</code> </td>
<td> <code>FOUND_ROWS</code> </td>
</tr>
<tr>
<td><code>GET_LOCK</code> </td>
<td> <code>RELEASE_LOCK</code> </td>
<td> <code>LOAD_FILE</code> </td>
</tr>
<tr>
<td><code>MASTER_POS_WAIT</code> </td>
<td> <code>NOW</code> </td>
<td> <code>SYSDATE</code> </td>
</tr>
<tr>
<td><code>CURRENT_TIMESTAMP</code> </td>
<td> <code>CURDATE</code> </td>
<td> <code>CURRENT_DATE</code> </td>
</tr>
<tr>
<td><code>CURTIME</code> </td>
<td> <code>CURRENT_TIME</code> </td>
<td> <code>DATABASE</code> </td>
</tr>
<tr>
<td><code>ENCRYPT</code> (只有一个参数调用) </td>
<td> <code>LAST_INSERT_ID</code> </td>
<td> <code>RAND</code> </td>
</tr>
<tr>
<td><code>UNIX_TIMESTAMP</code> (无参数调用) </td>
<td> <code>USER</code> </td>
<td> <code>BENCHMARK</code> </td>
</tr>
</table>
<p></p>
<p> 如果一个查询包含用户变量,引用 MySQL 系统数据库,或下列之一的格式,<code>SELECT ... IN SHARE MODE</code>,
<code>SELECT ... INTO OUTFILE ...</code>, <code>SELECT ... INTO DUMPFILE ...</code>
或 <code>SELECT * FROM AUTOINCREMENT_FIELD IS NULL</code> (检索最后一个插入 ID - ODBC
语句),该查询亦不可以被缓存。 </p>
<p> 然而,<code>FOUND ROWS()</code> 将返回正确的值,即使先前的查询是从缓存中读取的。 </p>
<p> 万一一个查询不使用任何表,或使用临时表,或用户对任何相关表有一个列权限,那么查询将不会被缓存。 </p>
<p> 在一个查询从查询缓存中读取前,MySQL 将检查用户对所有相关的数据库和表有 SELECT 权限。如果不是这种情况,缓存的结果将不能被使用。 </p>
<h3><a name="Query_Cache_Configuration"></a>6.9.2 查询缓存设置</h3>
<p> 查询缓存为了 <code>mysqld</code> 添加了几个 <code>MySQL</code> 系统变量,它可以在配置文件中被设置,或在启动
<code>mysqld</code> 时的命令行上设置。 </p>
<ul>
<li><code>query_cache_limit</code> 不缓存大于这个值的结果。(缺省为 1M)
<p></p>
<li><code>query_cache_min_res_unit</code> 这个变量从 4.1 被引进。 查询的结果 (已被传送到客户端的数据)
在结果检索期间被存储到查询缓存中。因而,数据不会以一个大块地处理。查询缓存在需要时分配块用于处理这个数据,所以当一个块被填充后,一个新的块被分配。甚为内存分配操作是昂贵的,查询缓存以最小的尺寸
<code>query_cache_min_res_unit</code> 分配块。当一个查询执行完成,最后的结果块被修整到实际数据的尺寸大小,以便未使用的内存被释放。
<ul>
<li> <code>query_cache_min_res_unit</code> 的缺省值为 4 KB,在大多数据情况下已够用了。
<li> 如果你有许多查询返回一个较小的结果,缺省的块尺寸可能会引起内存碎片 (显示为一个很大数量的空闲块(<code>Qcache_free_blocks</code>),这将引起查询缓存不得不因缺乏内存(<code>Qcache_lowmem_prunes</code>)而从缓存中删除查询)。在这种情况下,你应该减少
<code>query_cache_min_res_unit</code>。
<li> 如果你的主要查询返回的是大的结果集(查看 <code>Qcache_total_blocks</code> 和 <code>Qcache_queries_in_cache</code>),你可以通过增加
<code>query_cache_min_res_unit</code> 来增加性能。然而,要小心不要将它设得太大。
</ul>
<p></p>
<li><code>query_cache_size</code> 为了存储老的查询结果而分配的内存数量 (以字节指定) 。如果设置它为 0 ,查询缓冲将被禁止(缺省值为
0 )。
<li><code>query_cache_type</code> 这个可以被设置为 (只能是数字)
<table BORDER width="90%">
<tr>
<td><strong>选项 </strong> </td>
<td> <strong>含义 </strong> </td>
</tr>
<tr>
<td>0 </td>
<td> (OFF, 不缓存或重新得到结果) </td>
</tr>
<tr>
<td>1 </td>
<td> (ON, 缓存所有的结果,除了 <code>SELECT SQL_NO_CACHE ...</code> 查询) </td>
</tr>
<tr>
<td>2 </td>
<td> (DEMAND, 仅缓存 <code>SELECT SQL_CACHE ...</code> 查询) </td>
</tr>
</table>
</ul>
<p> 在一个线程(连接)内,查询缓存的行为可以被改变。句法如下所示: </p>
<p> <code>QUERY_CACHE_TYPE = OFF | ON | DEMAND</code> <code>QUERY_CACHE_TYPE =
0 | 1 | 2</code> </p>
<table BORDER width="95%">
<tr>
<td><strong>选项 </strong> </td>
<td> <strong>含义 </strong> </td>
</tr>
<tr>
<td>0 or OFF </td>
<td> 不缓存或重新得到结果 </td>
</tr>
<tr>
<td>1 or ON </td>
<td> 缓存所有的结果,除了 <code>SELECT SQL_NO_CACHE ...</code> 查询 </td>
</tr>
<tr>
<td>2 or DEMAND </td>
<td> 仅缓存 <code>SELECT SQL_CACHE ...</code> 查询 </td>
</tr>
</table>
<h3><a name="Query_Cache_in_SELECT"></a>6.9.3 在 <code>SELECT</code> 中的查询缓存选项</h3>
<p> 有两个可能的查询缓存相关的参数可以在一个 <code>SELECT</code> 查询中被指定: </p>
<p> <a name="IDX1519"></a> <a name="IDX1520"></a> </p>
<table BORDER width="95%">
<tr>
<td><strong>选项 </strong> </td>
<td> <strong>含义 </strong> </td>
</tr>
<tr>
<td><code>SQL_CACHE</code> </td>
<td> 如果 <code>QUERY_CACHE_TYPE</code> 为 <code>DEMAND</code>,允许该查询被缓存。如果 <code>QUERY_CACHE_TYPE</code>
为 <code>ON</code>,这是缺省的。如果 <code>QUERY_CACHE_TYPE</code> 为 <code>OFF</code>,它不做任何事
</td>
</tr>
<tr>
<td><code>SQL_NO_CACHE</code> </td>
<td> 使这个查询不被缓存,不允许这个查询被存储到高速缓存中 </td>
</tr>
</table>
<h3><a name="Query_Cache_Status_and_Maintenance"></a>6.9.4 查询缓存的状态和维护</h3>
<p> 使用 <code>FLUSH QUERY CACHE</code> 命令,你可以整理查询缓存,以更好的利用它的内存。这个命令不会从缓存中移除任何查询。<code>FLUSH
TABLES</code> 会转储清除查询缓存。 </p>
<p> <code>RESET QUERY CACHE</code> 使命从查询缓存中移除所有的查询结果。 </p>
<p> 你可以检查查询缓存在你的 MySQL 是否被引进: </p>
<pre>
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
1 row in set (0.00 sec)
</pre>
<p> 在 <code>SHOW STATUS</code> 中,你可以监视查询缓存的性能: </p>
<table BORDER width="95%">
<tr>
<td><strong>变量 </strong> </td>
<td> <strong>含义 </strong> </td>
</tr>
<tr>
<td><code>Qcache_queries_in_cache</code> </td>
<td> 在缓存中已注册的查询数目 </td>
</tr>
<tr>
<td><code>Qcache_inserts</code> </td>
<td> 被加入到缓存中的查询数目 </td>
</tr>
<tr>
<td><code>Qcache_hits</code> </td>
<td> 缓存采样数数目 </td>
</tr>
<tr>
<td><code>Qcache_lowmem_prunes</code> </td>
<td> 因为缺少内存而被从缓存中删除的查询数目 </td>
</tr>
<tr>
<td><code>Qcache_not_cached</code> </td>
<td> 没有被缓存的查询数目 (不能被缓存的,或由于 <code>QUERY_CACHE_TYPE</code>) </td>
</tr>
<tr>
<td><code>Qcache_free_memory</code> </td>
<td> 查询缓存的空闲内存总数 </td>
</tr>
<tr>
<td><code>Qcache_free_blocks</code> </td>
<td> 查询缓存中的空闲内存块的数目 </td>
</tr>
<tr>
<td><code>Qcache_total_blocks</code> </td>
<td> 查询缓存中的块的总数目 </td>
</tr>
</table>
<p> Total number of queries = <code>Qcache_inserts</code> + <code>Qcache_hits</code>
+ <code>Qcache_not_cached</code>. </p>
<p> 查询缓存使用变长的块,因而 <code>Qcache_total_blocks</code> 和 <code>Qcache_free_blocks</code>
可能显示查询缓存的碎片。在 <code>FLUSH QUERY CACHE</code> 之后,只有剩余一个单独的(大的)空闲块。 </p>
<p> 注意:每个查询最小需要两个块(一个用于存储查询文本,另一个或多个用于存储查询结果)。同样的,每个被一个查询使用的表需要一个块,但是,如果有两个或更多的查询使用同一张表,仅仅只需要分配一个块就行了。
</p>
<p> 你可以使用状态变量 <code>Qcache_lowmem_prunes</code> 来谐调查询缓存尺寸。它计数被从缓存中移除的查询,该查询的移除是为了释放内存,以缓存新建的查询。查询缓存使用一个
<code>least recently used</code> (<code>LRU</code>) 策略来判断从缓存中移除哪个查询。 </p>
<p> </p>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -