<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>猫窝私语 — Makumo&#039;s Blog &#187; 优化</title>
	<atom:link href="http://www.makumo.com/tag/optimization/feed" rel="self" type="application/rss+xml" />
	<link>http://www.makumo.com</link>
	<description>玛酷猫的温馨小窝，记录生活点点滴滴。</description>
	<lastBuildDate>Wed, 24 Mar 2010 07:08:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>优化SQL Server的内存占用之执行缓存</title>
		<link>http://www.makumo.com/sql_procedure_cache.cat</link>
		<comments>http://www.makumo.com/sql_procedure_cache.cat#comments</comments>
		<pubDate>Wed, 12 Nov 2008 07:06:26 +0000</pubDate>
		<dc:creator>玛酷猫</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://www.makumo.com/?p=134</guid>
		<description><![CDATA[（转载以便日后查找，原作者实在没找到是谁，不过还是很感谢作者） 在论坛上常见有朋友抱怨，说SQL Server太吃内存了。这里笔者根据经验简单介绍一下内存相关的调优知识。首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成：数据缓存(Data Buffer)、执行缓存(Procedure Cache)、以及SQL Server引擎程序。SQL Server引擎程序所占用缓存一般相对变化不大，则我们进行内存调优的主要着眼点在数据缓存和执行缓存的控制上。本文主要介绍一下执行缓存的调优。数据缓存的调优将在另外的文章中介绍。 对于减少执行缓存的占用，主要可以通过使用参数化查询减少内存占用。 1、使用参数化查询减少执行缓存占用 我们通过如下例子来说明一下使用参数化查询对缓存占用的影响。为方便试验，我们使用了一台没有其它负载的SQL Server进行如下实验。下面的脚本循环执行一个简单的查询，共执行10000次。 　　首先，我们清空一下SQL Server已经占用的缓存： dbcc freeproccache 　　然后，执行脚本： DECLARE @t datetime SET @t = getdate() SET NOCOUNT ON DECLARE @i INT, @count INT, @sql nvarchar(4000) SET @i = 20000 WHILE @i &#60;= 30000 BEGIN SET @sql = 'SELECT @count=count(*) FROM P_Order WHERE MobileNo = ' [...]]]></description>
			<content:encoded><![CDATA[<p>（转载以便日后查找，原作者实在没找到是谁，不过还是很感谢作者）</p>
<p>在论坛上常见有朋友抱怨，说SQL Server太吃内存了。这里笔者根据经验简单介绍一下内存相关的调优知识。首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成：数据缓存(Data Buffer)、执行缓存(Procedure Cache)、以及SQL Server引擎程序。SQL Server引擎程序所占用缓存一般相对变化不大，则我们进行内存调优的主要着眼点在数据缓存和执行缓存的控制上。本文主要介绍一下执行缓存的调优。数据缓存的调优将在另外的文章中介绍。</p>
<p>对于减少执行缓存的占用，主要可以通过使用参数化查询减少内存占用。</p>
<p><strong>1、使用参数化查询减少执行缓存占用</strong></p>
<p>我们通过如下例子来说明一下使用参数化查询对缓存占用的影响。为方便试验，我们使用了一台没有其它负载的SQL Server进行如下实验。下面的脚本循环执行一个简单的查询，共执行10000次。<br />
　　首先，我们清空一下SQL Server已经占用的缓存：</p>
<pre lang="sql" line="1">dbcc freeproccache</pre>
<p>　　然后，执行脚本：</p>
<pre lang="sql" line="1">DECLARE @t datetime
SET @t = getdate()
SET NOCOUNT ON
DECLARE @i INT, @count INT, @sql nvarchar(4000)
SET @i = 20000
WHILE @i &lt;= 30000
BEGIN
    SET @sql = 'SELECT @count=count(*) FROM P_Order WHERE MobileNo = ' + cast( @i as varchar(10) )
    EXEC sp_executesql @sql ,N'@count INT OUTPUT', @count OUTPUT
    SET @i = @i + 1
END
PRINT DATEDIFF( second, @t, current_timestamp )</pre>
<p>输出：<br />
DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。<br />
11</p>
<p>使用了11秒完成10000次查询。</p>
<p>我们看一下SQL Server缓存中所占用的查询计划：</p>
<pre lang="sql" line="1">Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans</pre>
<p>查询结果：共有2628条执行计划缓存在SQL Server中。它们所占用的缓存达到：<br />
92172288字节 = 90012KB = 87 MB。<br />
<span id="more-134"></span><br />
我们也可以使用dbcc memorystatus 命令来检查SQL Server的执行缓存和数据缓存占用。执行结果如下：<br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo001.gif"><img class="alignnone size-medium wp-image-136" title="图示一" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo001.gif" alt="" width="250" height="147" /></a><br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo002.gif"><img class="alignnone size-medium wp-image-137" title="图示二" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo002.gif" alt="" width="186" height="155" /></a><br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo003.gif"><img class="alignnone size-medium wp-image-138" title="图示三" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo003.gif" alt="" width="179" height="82" /></a></p>
<p>执行缓存占用了90088KB，有2629个查询计划在缓存里，有1489页空闲内存（每页8KB）可以被数据缓存和其他请求所使用。</p>
<p>我们现在修改一下前面的脚本，然后重新执行一下dbcc freeproccache。再执行一遍修改后的脚本：</p>
<pre lang="sql" line="1">DECLARE @t datetime
SET @t = getdate()
SET NOCOUNT ON
DECLARE @i INT, @count INT, @sql nvarchar(4000)
SET @i = 20000
WHILE @i &lt;= 30000
BEGIN
    SET @sql = 'select @count=count(*) FROM P_Order WHERE MobileNo = @i'
    EXEC sp_executesql @sql, N'@count int output, @i int', @count OUTPUT, @i
    SET @i = @i + 1
END
PRINT DATEDIFF( second, @t, current_timestamp )</pre>
<p>输出：<br />
DBCC 执行完毕。如果 DBCC 输出了错误信息，请与系统管理员联系。<br />
1<br />
即这次只用1秒钟即完成了10000次查询。</p>
<p>我们再看一下sys.dm_exec_cached_plans中的查询计划：</p>
<pre lang="sql" line="1">Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans</pre>
<p>查询结果：共有4条执行计划被缓存。它们共占用内存： 172032字节 = 168KB。<br />
如果执行dbcc memorystatus，则得到结果：<br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo004.gif"><img class="alignnone size-medium wp-image-139" title="图示四" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo004.gif" alt="" width="250" height="145" /></a><br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo005.gif"><img class="alignnone size-medium wp-image-140" title="图示五" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo005.gif" alt="" width="175" height="142" /></a><br />
<a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo006.gif"><img class="alignnone size-medium wp-image-141" title="图示六" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo006.gif" alt="" width="170" height="71" /></a><br />
有<span style="font-family: Calibri;">12875</span>页空闲内存<span style="font-family: Calibri;">(</span>每页<span style="font-family: Calibri;">8KB)</span>可以被数据缓存所使用。</p>
<p>到这里，我们已经看到了一个反差相当明显的结果。在现实中，这个例子中的前者，正是经常被使用的一种执行SQL脚本的方式（例如：在程序中通过合并字符串方式拼成一条SQL语句，然后通过ADO.NET或者ADO方式传入SQL Server执行）。</p>
<p>解释一下原因：</p>
<p>我们知道，SQL语句在执行前首先将被编译并通过查询优化引擎进行优化，从而得到优化后的执行计划，然后按照执行计划被执行。对于整体相似、仅仅是参数不同的SQL语句，SQL Server可以重用执行计划。但对于不同的SQL语句，SQL Server并不能重复使用以前的执行计划，而是需要重新编译出一个新的执行计划。同时，SQL Server在内存足够使用的情况下，此时并不主动清除以前保存的查询计划（注：对于长时间不再使用的查询计划，SQL Server也会定期清理）。这样，不同的SQL语句执行方式，就将会大大影响SQL Server中存储的查询计划数目。如果限定了SQL Server最大可用内存，则过多无用的执行计划占用，将导致SQL Server可用内存减少，从而在执行查询时尤其是大的查询时与磁盘发生更多的内存页交换。如果没有限定最大可用内存，则SQL Server由于可用内存减少，从而会占用更多内存。</p>
<p>对此，我们一般可以通过两种方式实现参数化查询：一是尽可能使用存储过程执行SQL语句（这在现实中已经成为SQL Server DBA的一条原则），二是使用sp_executesql 方式执行单个SQL语句（注意不要像上面的第一个例子那样使用sp_executesql)。</p>
<p>在现实的同一个软件系统中，大量的负载类型往往是类似的，所区别的也只是每次传入的具体参数值的不同。所以使用参数化查询是必要和可能的。另外，通过这个例子我们也看到，由于使用了参数化查询，不仅仅是优化了SQL Server内存占用，而且由于能够重复使用前面被编译的执行计划，使后面的执行不需要再次编译，最终执行10000次查询总共只使用了1秒钟时间。</p>
<p><strong>2、检查并分析SQL Server执行缓存中的执行计划</strong></p>
<p>通过上面的介绍，我们可以看到SQL缓存所占用的内存大小。也知道了SQL Server执行缓存中的内容主要是各种SQL语句的执行计划。则要对缓存进行优化，就可以通过具体分析缓存中的执行计划，看看哪些是有用的、哪些是无用的执行计划来分析和定位问题。</p>
<p>通过查询DMV: sys.dm_exec_cached_plans,可以了解数据库中的缓存情况，包括被使用的次数、缓存类型、占用的内存大小等。</p>
<pre lang="sql" line="1">SELECT usecounts, cacheobjtype, objtype,size_in_bytes, plan_handle FROM sys.dm_exec_cached_plans</pre>
<p><a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo007.gif"><img class="alignnone size-full wp-image-142" title="图示七" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo007.gif" alt="" width="500" height="131" /></a></p>
<p>通过缓存计划的plan_handle可以查询到该执行计划详细信息，包括所对应的SQL语句：</p>
<pre lang="sql" line="1">SELECT TOP 100 usecounts,
    objtype,
    p.size_in_bytes,
    [sql].[text]
FROM sys.dm_exec_cached_plans p
OUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sql
ORDER BY usecounts
</pre>
<p><a href="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo008.gif"><img class="alignnone size-full wp-image-135" title="图示8" src="http://www.makumo.com/wp-content/uploads/2008/11/sqlmemo008.gif" alt="" width="500" height="159" /></a></p>
<p>我们可以选择针对那些执行计划占用较大内存、而被重用次数较少的SQL语句进行重点分析。看其调用方式是否合理。另外，也可以对执行计划被重复使用次数较多的SQL语句进行分析，看其执行计划是否已经经过优化。进一步，通过对查询计划的分析，还可以根据需要找到系统中最占用IO、CPU时间、执行次数最多的一些SQL语句，然后进行相应的调优分析。篇幅所限，这里不对此进行过多介绍。读者可以查阅联机丛书中的：sys.dm_exec_query_plan内容得到相关帮助。</p>
<p>附：<br />
1:关于DBCC MEMORY，可以查看微软的知识库: <a href="http://support.microsoft.com/kb/907877/EN-US2">http://support.microsoft.com/kb/907877/EN-US</a><br />
2:关于sys.dm_exec_cached_plans和sys.dm_exec_sql_text，请参阅联机丛书。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makumo.com/sql_procedure_cache.cat/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web 前端优化最佳实践之内容篇[转]</title>
		<link>http://www.makumo.com/best_practices_for_speeding_up_your_web_site_content.cat</link>
		<comments>http://www.makumo.com/best_practices_for_speeding_up_your_web_site_content.cat#comments</comments>
		<pubDate>Fri, 27 Jun 2008 13:21:24 +0000</pubDate>
		<dc:creator>玛酷猫</dc:creator>
				<category><![CDATA[他山之石]]></category>
		<category><![CDATA[页面设计]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://www.makumo.com/2008/06/best_practices_for_speeding_up_your_web_site_content.html</guid>
		<description><![CDATA[（朋友发给我的，觉得很不错就转到这来了，方便随时查看。） Yahoo! 的 Exceptional Performance team 在 Web 前端方面作出了卓越的贡献。广为人知的优化规则也由 13 条到 14 条，再到 20 条，乃至现在的 34 条&#8211;真是与时俱进啊。最新的 34 条也针对不同的角度做了分类。 面向内容的优化规则目前有 10 条。 1. 尽量减少 HTTP 请求 (Make Fewer HTTP Requests) 作为第一条，可能也是最重要的一条。根据 Yahoo! 研究团队的数据分析，有很大一部分用户访问会因为这一条而取得最大受益。有几种常见的方法能切实减少 HTTP 请求：     * 1) 合并文件，比如把多个 CSS 文件合成一个；     * 2) CSS Sprites 利用 CSS background 相关元素进行背景图绝对定位；参见：CSS Sprites: Image Slicing&#8217;s Kiss of [...]]]></description>
			<content:encoded><![CDATA[<p>（朋友发给我的，觉得很不错就转到这来了，方便随时查看。）</p>
<p>Yahoo! 的 Exceptional Performance team 在 Web 前端方面作出了卓越的贡献。广为人知的优化规则也由 13 条到 14 条，再到 20 条，乃至现在的 34 条&#8211;真是与时俱进啊。最新的 34 条也针对不同的角度做了分类。</p>
<p>面向内容的优化规则目前有 10 条。</p>
<p>1. 尽量减少 HTTP 请求 (Make Fewer HTTP Requests)</p>
<p>作为第一条，可能也是最重要的一条。根据 Yahoo! 研究团队的数据分析，有很大一部分用户访问会因为这一条而取得最大受益。有几种常见的方法能切实减少 HTTP 请求：<br />
    * 1) 合并文件，比如把多个 CSS 文件合成一个；<br />
    * 2) CSS Sprites 利用 CSS background 相关元素进行背景图绝对定位；参见：CSS Sprites: Image Slicing&#8217;s Kiss of Death<br />
    * 3) 图像地图<br />
    * 4) 内联图象 使用 data: URL scheme 在实际的页面嵌入图像数据.</p>
<p>2. 减少 DNS 查找 (Reduce DNS Lookups)</p>
<p>必须明确的一点，DNS 查找的开销是很大的。另外，我倒是觉得这是 Yahoo! 所有站点的通病，Yahoo！主站点可能还不够明显，一些分站点，存在明显的类似问题。对于国内站点来说，如果过多的使用了站外的 Widget ，也很容易引起过多的 DNS 查找问题。</p>
<p>3. 避免重定向 (Avoid Redirects)</p>
<p>不是绝对的避免，尽量减少。另外，应该注意一些不必要的重定向。比如对 Web 站点子目录的后面添加个 / (Slash) ，就能有效避免一次重定向。http://www.dbanotes.net/arch 与 http://www.dbanotes.net/arch/ 二者之间是有差异的。如果是 Apache 服务器，通过配置 Alias 或mod_rewrite 或是 DirectorySlash 能够消除这个问题。</p>
<p>4. 使得 Ajax 可缓存 (Make Ajax Cacheable)</p>
<p>响应时间对 Ajax 来说至关重要，否则用户体验绝对好不到哪里去。提高响应时间的有效手段就是 Cache 。其它的一些优化规则对这一条也是有效的。</p>
<p>5. 延迟载入组件 (Post-load Components)</p>
<p>6. 预载入组件 (Preload Components)</p>
<p>上面两条严格说来，都是属于异步这个思想灵活运用的事儿。</p>
<p>7. 减少 DOM 元素数量 (Reduce the Number of DOM Elements)</p>
<p>8. 切分组件到多个域 (Split Components Across Domains)</p>
<p>主要的目的是提高页面组件并行下载能力。但不要跨太多域名，否则就和第二条有些冲突了。</p>
<p>9. 最小化 iframe 的数量 (Minimize the Number of iframes)</p>
<p>熟悉 SEO 的朋友知道 iframe 是 SEO 的大忌。针对前端优化来说 iframe 有其好处，也有其弊端，一分为二看问题吧。</p>
<p>10. 杜绝 http 404 错误 (No 404s)</p>
<p>对页面链接的充分测试加上对 Web 服务器 error 日志的不断跟踪能有效减少 404 错误，亦能提升用户体验。值得一提的是，CSS 与 Java Script 引起的 404 错误因为定位稍稍&#8221;难&#8221;一点而往往容易被忽略。</p>
<p>这是内容篇的 10 条。应该说具体引导性的内容还不够详细。逐渐会根据自己的理解补充上来。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.makumo.com/best_practices_for_speeding_up_your_web_site_content.cat/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

