九大对象:
内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用
1-out:
javax.servlet.jsp.JspWriter类型,代表输出流的对象。作用域为page(页面执行期)
request:javax.servlet.ServletRequest的子类型,此对象封装了由WEB浏览器或其它客户端生成地HTTP
请求的细节(参数,属性,头标和数据)。作用域为request(用户请求期)。
方法由可查看API
response:javax.servlet.ServletResponse的子类型,此对象封装了返回到HTTP客户端的输出,向页面
作者提供设置响应头标和状态码的方式。经常用来设置HTTP标题,添加cookie,设置响应内容的类型和状
态,发送HTTP重定向和编码URL。作用域为page(页面执行期)。
pageContext:javax.servlet.jsp.PageContext(抽象类)类型,作用域为page(页面执行期)。此对象
提供所有四个作用域层次的属性查询和修改能力,它也提供了转发请求到其它资源和包含其他资源的方法
:
该对象的方法都是抽象方法
session:javax.servlet.http.HttpSession类型,主要用于跟踪对话。作用域session(会话期—)。
HttpSession是一个类似哈希表的与单一WEB浏览器会话相关的对象,它存在于HTTP请求之间,可以存储任
何类型的命名对象。
如果不需要在请求之间跟踪会话对象,可以通过在page指令中指定session="false"
需要记住的是pageContext对象也可以与session.getAttribute(),session.setAttribute()一样的方式取
得并设置会话属性。
application:javax.servlet.ServletContext类型,servlet的环境通过调用getServletConfig
().getContext()方法获得。作用域是application(整个程序运行期)。它提供了关于服务器版本,应用
级初始化参数和应用内资源绝对路径,注册信息的方式
config:javax.servlet.ServletConfig,作用域为page(页面执行期)
exception:java.lang.Throwable,通过JSP错误页面中一个catch块已经益出但没有捕获的
java.lang.Throwable的任意实例,传向了errorPage的URI。作用域为page(页面执行期)。注意
exception只有在page指令中具有属性isErrorPage="true"时才有效。
page:java.lang.Object类型,指向页面自身的方式。作用域为page(页面执行期
JSP中九大内置对象为:
request 请求对象 类型 javax.servlet.ServletRequest 作用域 Request
response 响应对象 类型 javax.servlet.SrvletResponse 作用域 Page
pageContext 页面上下文对象 类型 javax.servlet.jsp.PageContext 作用域 Page
session 会话对象 类型 javax.servlet.http.HttpSession 作用域 Session
application 应用程序对象 类型 javax.servlet.ServletContext 作用域 Application
out 输出对象 类型 javax.servlet.jsp.JspWriter 作用域 Page
config 配置对象 类型 javax.servlet.ServletConfig 作用域 Page
page 页面对象 类型 javax.lang.Object 作用域 Page
exception 例外对象 类型 javax.lang.Throwable 作用域 page
request 对象代表的是来自客户端的请求,例如我们在FORM表单中填写的信息等,是最常用的对象
常用的方法有:getParameter、getParameterNames 和getParameterValues 通过调用这几个方法来获取请求对象中所包含的参数的值。
response 对象代表的是对客户端的响应,也就是说可以通过response 对象来组织发送到客户端的数据。但是由于组织方式比较底层,所以不建议普通读者使用,需要向客户端发送文字时直接使用
pageContext 对象直译时可以称作“页面上下文”对象,代表的是当前页面运行的一些属性
常用的方法有 :findAttribute、getAttribute、getAttributesScope 和getAttributeNamesInScope
一般情况下pageContext对象用到得也不是很多,只有在项目所面临的情况比较复杂的情况下,才会利用到页面属性来辅助处理。
session 对象代表服务器与客户端所建立的会话,当需要在不同的JSP页面中保留客户信息的情况下使用,比如在线购物、客户轨迹跟踪等。“session” 对象建立在cookie的基础上,所以使用时应注意判断一下客户端是否打开了cookie。常用的方法包括getId、 getValue、 getValueNames和putValue等。
概要
HTTP是无状态(stateless)协议;
Web Server 对每一个客户端请求都没有历史记忆;
Session用来保存客户端状态信息;
由Web Server 写入;
存于客户端;
客户端的每次访问都把上次的session记录传递给Web Server;
Web Server读取客户端提交的session来获取客户端的状态信息
application 对象负责提供应用程序在服务器中运行时的一些全局信息,常用的方法有getMimeType和getRealPath等。
out 对象代表了向客户端发送数据的对象,与“response” 对象不同,通过“out” 对象发送的内容将是浏览器需要显示的内容,是文本一级的,可以通过“out” 对象直接向客户端写一个由程序动态生成HTML文件。常用的方法除了pirnt和println之外,还包括clear、clearBuffer、 flush、getBufferSize和getRemaining,这是因为“out” 对象内部包含了一个缓冲区,所以需要一些对缓冲区进行操作的方法
“config” 对象提供一些配置信息,常用的方法有getInitParameter和getInitParameterNames,以获得Servlet初始化时的参数。
“page” 对象代表了正在运行的由JSP文件产生的类对象,不建议一般读者使用。
“exception” 对象则代表了JSP文件运行时所产生的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了“<%@ page isErrorPage="true "%>”的JSP文件中四个作用域:
何为作用域
先让我们看看效果:
大概流程是这样的,我们访问04-01/index.jsp的时候,分别对pageContext, request, session,
application四个作用域中的变量进行累加。(当然先判断这个变量是不是存在,如果变量不存在,则要
把变量初始化成1。)计算完成后就从index.jsp执行forward跳转到test.jsp。在test.jsp里再进行一次
累加,然后显示出这四个整数来。
从显示的结果来看,我们可以直观的得出结论:
page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,它们就不见了。
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
session和application里的变量一直在累加,开始还看不出区别,只要关闭浏览器,再次重启浏览器访问
这页,session里的变量就重新计算了。
application里的变量一直在累加,除非你重启tomcat,否则它会一直变大。
而作用域规定的是变量的有效期限。
如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。
从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。
所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使
用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。
所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个
请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被
称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。
整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务
器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。
application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application
中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,
session都是完全隔离的,无论如何修改都不会影响其他人的数据。
我们使用public Object getAttribute(String name)获得变量值,使用public void setAttribute
(String name, Object value)将变量值保存到对应作用域中。举个pageContext的例子就是:
// page
Integer countPage = (Integer) pageContext.getAttribute("countPage");
if (countPage == null) {
pageContext.setAttribute("countPage", 1);
} else {
pageContext.setAttribute("countPage", countPage + 1);
}
这里先从pageContext中取出名为countPage的整数,因为返回的都是java.lang.Object类型,所以需要强
制转换成我们需要的整形。这里取得的变量如果不存在就会返回null,通过判断countPage == null来辨
别变量是否存在,如果不存在就设置为1,如果存在就进行累加,最后使用setAttribute()方法将修改后
的变量值放入pageContext。
将其中的pageContext换成request, session, application就可以操作其他三个作用域中的变量。%@>
内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用
1-out:
javax.servlet.jsp.JspWriter类型,代表输出流的对象。作用域为page(页面执行期)
request:javax.servlet.ServletRequest的子类型,此对象封装了由WEB浏览器或其它客户端生成地HTTP
请求的细节(参数,属性,头标和数据)。作用域为request(用户请求期)。
方法由可查看API
response:javax.servlet.ServletResponse的子类型,此对象封装了返回到HTTP客户端的输出,向页面
作者提供设置响应头标和状态码的方式。经常用来设置HTTP标题,添加cookie,设置响应内容的类型和状
态,发送HTTP重定向和编码URL。作用域为page(页面执行期)。
pageContext:javax.servlet.jsp.PageContext(抽象类)类型,作用域为page(页面执行期)。此对象
提供所有四个作用域层次的属性查询和修改能力,它也提供了转发请求到其它资源和包含其他资源的方法
:
该对象的方法都是抽象方法
session:javax.servlet.http.HttpSession类型,主要用于跟踪对话。作用域session(会话期—)。
HttpSession是一个类似哈希表的与单一WEB浏览器会话相关的对象,它存在于HTTP请求之间,可以存储任
何类型的命名对象。
如果不需要在请求之间跟踪会话对象,可以通过在page指令中指定session="false"
需要记住的是pageContext对象也可以与session.getAttribute(),session.setAttribute()一样的方式取
得并设置会话属性。
application:javax.servlet.ServletContext类型,servlet的环境通过调用getServletConfig
().getContext()方法获得。作用域是application(整个程序运行期)。它提供了关于服务器版本,应用
级初始化参数和应用内资源绝对路径,注册信息的方式
config:javax.servlet.ServletConfig,作用域为page(页面执行期)
exception:java.lang.Throwable,通过JSP错误页面中一个catch块已经益出但没有捕获的
java.lang.Throwable的任意实例,传向了errorPage的URI。作用域为page(页面执行期)。注意
exception只有在page指令中具有属性isErrorPage="true"时才有效。
page:java.lang.Object类型,指向页面自身的方式。作用域为page(页面执行期
JSP中九大内置对象为:
request 请求对象 类型 javax.servlet.ServletRequest 作用域 Request
response 响应对象 类型 javax.servlet.SrvletResponse 作用域 Page
pageContext 页面上下文对象 类型 javax.servlet.jsp.PageContext 作用域 Page
session 会话对象 类型 javax.servlet.http.HttpSession 作用域 Session
application 应用程序对象 类型 javax.servlet.ServletContext 作用域 Application
out 输出对象 类型 javax.servlet.jsp.JspWriter 作用域 Page
config 配置对象 类型 javax.servlet.ServletConfig 作用域 Page
page 页面对象 类型 javax.lang.Object 作用域 Page
exception 例外对象 类型 javax.lang.Throwable 作用域 page
request 对象代表的是来自客户端的请求,例如我们在FORM表单中填写的信息等,是最常用的对象
常用的方法有:getParameter、getParameterNames 和getParameterValues 通过调用这几个方法来获取请求对象中所包含的参数的值。
response 对象代表的是对客户端的响应,也就是说可以通过response 对象来组织发送到客户端的数据。但是由于组织方式比较底层,所以不建议普通读者使用,需要向客户端发送文字时直接使用
pageContext 对象直译时可以称作“页面上下文”对象,代表的是当前页面运行的一些属性
常用的方法有 :findAttribute、getAttribute、getAttributesScope 和getAttributeNamesInScope
一般情况下pageContext对象用到得也不是很多,只有在项目所面临的情况比较复杂的情况下,才会利用到页面属性来辅助处理。
session 对象代表服务器与客户端所建立的会话,当需要在不同的JSP页面中保留客户信息的情况下使用,比如在线购物、客户轨迹跟踪等。“session” 对象建立在cookie的基础上,所以使用时应注意判断一下客户端是否打开了cookie。常用的方法包括getId、 getValue、 getValueNames和putValue等。
概要
HTTP是无状态(stateless)协议;
Web Server 对每一个客户端请求都没有历史记忆;
Session用来保存客户端状态信息;
由Web Server 写入;
存于客户端;
客户端的每次访问都把上次的session记录传递给Web Server;
Web Server读取客户端提交的session来获取客户端的状态信息
application 对象负责提供应用程序在服务器中运行时的一些全局信息,常用的方法有getMimeType和getRealPath等。
out 对象代表了向客户端发送数据的对象,与“response” 对象不同,通过“out” 对象发送的内容将是浏览器需要显示的内容,是文本一级的,可以通过“out” 对象直接向客户端写一个由程序动态生成HTML文件。常用的方法除了pirnt和println之外,还包括clear、clearBuffer、 flush、getBufferSize和getRemaining,这是因为“out” 对象内部包含了一个缓冲区,所以需要一些对缓冲区进行操作的方法
“config” 对象提供一些配置信息,常用的方法有getInitParameter和getInitParameterNames,以获得Servlet初始化时的参数。
“page” 对象代表了正在运行的由JSP文件产生的类对象,不建议一般读者使用。
“exception” 对象则代表了JSP文件运行时所产生的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了“<%@ page isErrorPage="true "%>”的JSP文件中四个作用域:
何为作用域
先让我们看看效果:
大概流程是这样的,我们访问04-01/index.jsp的时候,分别对pageContext, request, session,
application四个作用域中的变量进行累加。(当然先判断这个变量是不是存在,如果变量不存在,则要
把变量初始化成1。)计算完成后就从index.jsp执行forward跳转到test.jsp。在test.jsp里再进行一次
累加,然后显示出这四个整数来。
从显示的结果来看,我们可以直观的得出结论:
page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,它们就不见了。
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
session和application里的变量一直在累加,开始还看不出区别,只要关闭浏览器,再次重启浏览器访问
这页,session里的变量就重新计算了。
application里的变量一直在累加,除非你重启tomcat,否则它会一直变大。
而作用域规定的是变量的有效期限。
如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。
从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。
所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使
用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。
所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个
请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被
称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。
整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务
器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。
application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application
中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,
session都是完全隔离的,无论如何修改都不会影响其他人的数据。
我们使用public Object getAttribute(String name)获得变量值,使用public void setAttribute
(String name, Object value)将变量值保存到对应作用域中。举个pageContext的例子就是:
// page
Integer countPage = (Integer) pageContext.getAttribute("countPage");
if (countPage == null) {
pageContext.setAttribute("countPage", 1);
} else {
pageContext.setAttribute("countPage", countPage + 1);
}
这里先从pageContext中取出名为countPage的整数,因为返回的都是java.lang.Object类型,所以需要强
制转换成我们需要的整形。这里取得的变量如果不存在就会返回null,通过判断countPage == null来辨
别变量是否存在,如果不存在就设置为1,如果存在就进行累加,最后使用setAttribute()方法将修改后
的变量值放入pageContext。
将其中的pageContext换成request, session, application就可以操作其他三个作用域中的变量。%@>
QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC。每个Cache都是以SQL文本作为key来存的。
原理
QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。
不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理:
过滤所有注释
去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。
下面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三条SQL会被存储在三个不同的缓存里,虽然它们的结果都是一样的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';
目前只有select语句会被cache,其他类似show,use的语句则不会被cache。
因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。
也就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数据库的负担,而不是减轻负担。我一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。
那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。
存储块
在本节里“存储块”和“block”是同一个意思
QC缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。
除了查询结果需要存储块之外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。
通过观察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的比例如果接近1:2,则说明当前的query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。
Qcache_queries_in_cache*query_cache_min_res_unit(sql文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可以尝试减小query_cache_min_res_unit的值。
调整大小
如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。
启动参数
show variables like 'query_cache%'可以看到这些信息。
query_cache_limit:如果单个查询结果大于这个值,则不Cache
query_cache_size:分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于40KB,则相当于禁用QC。QC存储的最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。
query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。
query_cache_min_res_unit:每次给QC结果分配内存的大小
状态
show status like 'Qcache%'可以看到这些信息。
Qcache_free_blocks:当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。
Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size
Qcache_hits:自mysql进程启动起,cache的命中数量
Qcache_inserts:自mysql进程启动起,被增加进QC的数量
Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。
Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等)
Qcache_queries_in_cache:当前被cache的SQL数量
Qcache_total_blocks:在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个blocks,第一个block用来存储sql语句文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个block为2KB(先allocate4KB,然后释放多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个block来存储表信息。也就是说,block会被用在三处地方:表信息,SQL文本,查询结果。
详细出处参考:http://www.jb51.net/article/15179.htm
原理
QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。
不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理:
过滤所有注释
去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。
下面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三条SQL会被存储在三个不同的缓存里,虽然它们的结果都是一样的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';
目前只有select语句会被cache,其他类似show,use的语句则不会被cache。
因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。
也就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数据库的负担,而不是减轻负担。我一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。
那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。
存储块
在本节里“存储块”和“block”是同一个意思
QC缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。
除了查询结果需要存储块之外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。
通过观察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的比例如果接近1:2,则说明当前的query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。
Qcache_queries_in_cache*query_cache_min_res_unit(sql文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可以尝试减小query_cache_min_res_unit的值。
调整大小
如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。
启动参数
show variables like 'query_cache%'可以看到这些信息。
query_cache_limit:如果单个查询结果大于这个值,则不Cache
query_cache_size:分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于40KB,则相当于禁用QC。QC存储的最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。
query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。
query_cache_min_res_unit:每次给QC结果分配内存的大小
状态
show status like 'Qcache%'可以看到这些信息。
Qcache_free_blocks:当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。
Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size
Qcache_hits:自mysql进程启动起,cache的命中数量
Qcache_inserts:自mysql进程启动起,被增加进QC的数量
Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。
Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等)
Qcache_queries_in_cache:当前被cache的SQL数量
Qcache_total_blocks:在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个blocks,第一个block用来存储sql语句文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个block为2KB(先allocate4KB,然后释放多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个block来存储表信息。也就是说,block会被用在三处地方:表信息,SQL文本,查询结果。
详细出处参考:http://www.jb51.net/article/15179.htm
最近找了款軟件可以把繫統更換成任何一國傢的預言界麵
有需要的朋友來試試
用法:
1.下载
下载文件
2.下载想要装的语言包(请用 计算机-属性 确认自己的Vista版本,简体中文在连接里有选)
32-bit Vista RTM
32-bit Vista SP1
64-bit Vista RTM
64-bit Vista SP1
3.解压缩Vistalizator到某地方并运行
4.点左上角的“Add Language”然后选择刚刚下载的语言包文件 (选择后需要等一小下)
5.点Install即可
6.重新启动后就能看到崭新的中文操作界面了
*如果要换回英文,或者换到其他语言,打开程序,在下拉列表里选择装过的语言,点“Change Language”就Ok了。
有需要的朋友來試試
用法:
1.下载
下载文件 2.下载想要装的语言包(请用 计算机-属性 确认自己的Vista版本,简体中文在连接里有选)
32-bit Vista RTM
32-bit Vista SP1
64-bit Vista RTM
64-bit Vista SP1
3.解压缩Vistalizator到某地方并运行
4.点左上角的“Add Language”然后选择刚刚下载的语言包文件 (选择后需要等一小下)
5.点Install即可
6.重新启动后就能看到崭新的中文操作界面了
*如果要换回英文,或者换到其他语言,打开程序,在下拉列表里选择装过的语言,点“Change Language”就Ok了。
突然间想下载一个操作系统的语言包,主要是想下载日文语言包。毕竟对于日语的操作系统还没玩过,要是专门去装一个日文版的操作系统的话,可能还没有那个水平,使用过程中也有很大的问题,所以在现有的基础上安装日语语言包,可以轻送切换到中文和日文。
以下是各种语言包的下载地址:
32位:
简体中文:
下载文件
繁体中文(香港):
下载文件
日语:
下载文件
韩语:
下载文件
英文:
下载文件
64位:
简体中文:
下载文件
繁体中文(香港):
下载文件
日语:
下载文件
韩语:
下载文件
以下是各种语言包的下载地址:
32位:
简体中文:
下载文件 繁体中文(香港):
下载文件 日语:
下载文件 韩语:
下载文件 英文:
下载文件 64位:
简体中文:
下载文件 繁体中文(香港):
下载文件 日语:
下载文件 韩语:
下载文件
一大早跑到卡巴365去兑换激活码,最近下载了英文版的卡巴斯基,没想到拿自己之前的激活码却激活不了,大概是中国地区买的卡巴斯基只能使用中文版的卡巴斯基吧!这个问题还得问一下卡巴斯基的客服才知道。在兑换激活码的同时,逛了一下卡巴斯基中文论坛。发现卡巴斯基2011的RC版本都已经发布很多天了。很不幸的是还没有中文版,不过等到2011正式版发布的时候,我想中文版的2011正式版的也会有的。
目前能下载到的RC版本中只有俄语、英语、法语、德语
以下是下载地址:
德语下载地址:
下载文件
下载文件
法语下载地址:
下载文件
下载文件
俄语下载地址:
下载文件
下载文件
英文下载地址:
下载文件
下载文件
目前能下载到的RC版本中只有俄语、英语、法语、德语
以下是下载地址:
德语下载地址:
下载文件
下载文件 法语下载地址:
下载文件
下载文件 俄语下载地址:
下载文件
下载文件 英文下载地址:
下载文件
下载文件
在看网络视频教程的时候,看到安装的虚拟主机里面有几块网卡,自己也安装了虚拟主机,但是默认每次都只有一块网卡,所以对此到互联网查了一下。
原来很简单,只需要在
这样就解决了我们的需要。
具体的操作如下图:






原来很简单,只需要在
Edit virtual machine settings
选项里面的Hardware选项卡里面有一个Add按钮,只需在点击Add按钮,即可选择你要添加的虚拟硬件。这样就解决了我们的需要。
具体的操作如下图:
下载了一个网易的闪电邮,自己也把域名邮箱转移到了网易的域名邮箱。在国内来说,邮箱做得最好的还是属于网易了。这是众所周知的。
以下是用闪电邮的设置
您可以通过电脑客户端软件更好地收发邮件,服务器地址:
POP3:pop.ym.163.com 默认端口为:110
SMTP:smtp.ym.163.com 默认端口为:25
以下是我的邮件客户端的配置

以下是用闪电邮的设置
您可以通过电脑客户端软件更好地收发邮件,服务器地址:
POP3:pop.ym.163.com 默认端口为:110
SMTP:smtp.ym.163.com 默认端口为:25
以下是我的邮件客户端的配置
之前下载了一个名为Poser 2010 的软件,这个软件是用来设计任务造型的软件,对于我来说,没有多大用处,毕竟自己不是搞这一方面的,今天由于学校的客户端的问题,导致自己重新安装系统。安装系统之后,便是安装软件的过程,无意间看到自己之前下载的这个软件,便安装了一下,整个安装过程是非常的长啊。大概需要20多分钟,这个时间,我可以重新安装一次系统了。安装完之后便启动该软件,谁知,需要序列号,该软件需要注册的。到网上找了一下,结果发现都是国外的一些下载站点,下载还需要钱。但是那些并不是激活码,而是软件而已。自己寻找了一段时间,终于发现原来,激活码就在下载的软件的一个文件夹里面。打开一个文本文件,里面就是激活码具体的文件在下载的文件的CYGi
Smith_Micro_Poser_Pro_2010_v8.0-CYGiSO--------------------------------------Poser Pro : XP20CCD-0001-00AQ-ZAS0-000D-JAC8Queue Manager : QM20CCD-9999-00AD-HTP0-100N-BBP0Cinema4D : PC20CCD-0001-00AT-KVY0-600C-YFA2Maya : PM20CCD-0001-00BH-MBC0-200V-XUU4Max : PX20CCD-0001-00AW-RTB0-800U-UXT4Of course unselect 'Submit Registration Online' and block the App with firewallEnjoy, Team CYGiSO
在Windows平台,我们可以使用cmd命令来操作一些基本的的命令。
默认的颜色是黑色的背景,白色的字体颜色。
我们通常需要切换过来。
使用以下命令即可
cmd
color f1;
我们也可以直接敲一个color就可以显示默认的颜色。
自定义输入color fc即可查看其它的颜色。
默认的颜色是黑色的背景,白色的字体颜色。
我们通常需要切换过来。
使用以下命令即可
cmd
color f1;
我们也可以直接敲一个color就可以显示默认的颜色。
自定义输入color fc即可查看其它的颜色。






