<?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>优化 &#8211; LPC影子技术分享</title>
	<atom:link href="https://www.mudbest.com/tag/%E4%BC%98%E5%8C%96/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.mudbest.com</link>
	<description>行影不离,忘之却步.</description>
	<lastBuildDate>Fri, 02 Nov 2012 10:34:14 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.1</generator>
	<item>
		<title>windows下配置php+xdebug</title>
		<link>https://www.mudbest.com/windows%e4%b8%8b%e9%85%8d%e7%bd%aephpxdebug/</link>
		
		<dc:creator><![CDATA[hkshadow]]></dc:creator>
		<pubDate>Fri, 02 Nov 2012 10:32:31 +0000</pubDate>
				<category><![CDATA[分享]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[调试]]></category>
		<guid isPermaLink="false">http://www.mudbest.com/?p=1661</guid>

					<description><![CDATA[前言： Xdebug最常用的就是错误提示，它可以将一些脚本错误的详细信息给展示出来，甚至到错误的变量。对于程序 ... <a title="windows下配置php+xdebug" class="read-more" href="https://www.mudbest.com/windows%e4%b8%8b%e9%85%8d%e7%bd%aephpxdebug/" aria-label="阅读 windows下配置php+xdebug">阅读更多</a>]]></description>
										<content:encoded><![CDATA[<p>前言：<br />
Xdebug最常用的就是错误提示，它可以将一些脚本错误的详细信息给展示出来，甚至到错误的变量。对于程序最优它也有着必然的作用，配合Kcachegrind对Xdebug生成的日志文件进行性能分析，WINDOWS下常用Wincachegrind。</p>
<p>在这里再提示一下</p>
<pre class="brush: plain; title: ; notranslate">
PHP 5.2.X的版本用zend_extension_ts加载
PHP 5.3.X的版本要用 zend_extension加载 
</pre>
<p><span id="more-1661"></span><br />
首先下载php相对应的版本Xdebug，可以在页面输出</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
phpinfo();
?&gt;
</pre>
<p>将打印出来的所有字符串复制到http://www.xdebug.org/wizard.php进行自动检测，会根据当前PHP版本进行提示下载。</p>
<p>将下载后的DLL组件放在PHP目录的/ext目录，例如d:/webserver/php5.3/ext。</p>
<p>最终配置：</p>
<pre class="brush: plain; title: ; notranslate">
;zend_extension_ts=&quot;D:/web_server/xdebug/php_xdebug-2.2.1-5.3-vc9-nts.dll&quot;
zend_extension=&quot;D:/web_server/xdebug/php_xdebug-2.2.1-5.3-vc9.dll&quot;
xdebug.auto_trace=on
xdebug.collect_return=on
xdebug.trace_output_dir=&quot;D:/web_server/xdebug/tracelog&quot;
xdebug.profiler_enable=on
xdebug.profiler_output_dir=&quot;D:/web_server/xdebug/profilerlog&quot; 
xdebug.default_enable = On  
xdebug.show_exception_trace = On  
xdebug.show_local_vars = 1  
xdebug.max_nesting_level = 50  
xdebug.var_display_max_depth = 6  
xdebug.dump_once = On  
xdebug.dump_globals = On  
xdebug.dump_undefined = On  
xdebug.dump.REQUEST = *  
xdebug.dump.SERVER = REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT  

xdebug.trace_format = 0  
xdebug.auto_trace = On  
xdebug.trace_output_name = trace.%c.%p  
xdebug.collect_params = 4 
xdebug.collect_includes = On  
xdebug.show_mem_delta = On  
</pre>
<pre class="brush: plain; title: ; notranslate">
;参数解释：
;zend_extension_ts=&quot;d:/webserver/php5/ext/php_xdebug.dll&quot;
;加载xdebug模块。这里不能用extension=php_xdebug.dll的方式加载，必须要以zend的方式加载，否则安装上后，phpinfo是显示不出xdebug这个项的。
;xdebug.auto_trace=on;
;自动打开“监测函数调用过程”的功模。该功能可以在你指定的目录中将函数调用的监测信息以文件的形式输出。此配置项的默认值为off。
;xdebug.collect_params=on;
;打开收集“函数参数”的功能。将函数调用的参数值列入函数过程调用的监测信息中。此配置项的默认值为off。
;xdebug.collect_return=on
;打开收集“函数返回值”的功能。将函数的返回值列入函数过程调用的监测信息中。此配置项的默认值为off。
;xdebug.trace_output_dir=”c:\Temp\xdebug”
;设定函数调用监测信息的输出文件的路径。
;xdebug.profiler_enable=on
;打开效能监测器。
;xdebug.profiler_output_dir=&quot;D:/web_server/xdebug/profilerlog&quot; 
;设定效能监测信息输出文件的路径。 

/*
xdebug.dump_once、xdebug.dump_globals、xdebug.dump_undefined 和 xdebug.dump_SUPERGLOBAL 设置（其中 SUPERGLOBAL 可以是 COOKIE、FILES、GET、POST、REQUEST、SERVER 或 SESSION）用于控制哪些 PHP 超全局变量将被包含在所有诊断结果中。  
  
将xdebug.dump_globals 设为 On 以转储名为 xdebug.dump_SUPERGLOBAL 设置中的超全局变量。例如，xdebug.dump_SERVER = REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT 将打印 PHP 超全局变量 $_SERVER&#x5B;'REQUEST_METHOD']、$_SERVER&#x5B;'REQUEST_URI'] 和 $_SERVER&#x5B;'HTTP_USER_AGENT']。如果需要打印超全局变量数组中的所有值，请使用星号 (*)，例如 xdebug.dump_REQUEST=*。如果进一步将 xdebug.dump_undefined 设为 On 并且不设定指定的超全局变量，则仍用值 undefined 打印变量。  
  
即使捕捉到异常，代码行 xdebug.show_exception_trace = On 仍将强制执行异常跟踪。代码行 xdebug.show_local_vars = 1 将打印每个函数调用的最外围中的所有局部变量，包括尚未初始化的变量。而 xdebug.var_display_max_depth = 6 表示转储复杂变量的深度。  

跟踪代码  
  
解决错误 —— 如解开神秘谋杀之谜 —— 通常要求构造详细的时间线。例如，内存泄漏通常不会把自身表明为一个错误计算。相反，操作将正常进行，直至内存用尽，然后应用程序突然终止。如果内存泄漏由于某些请求而恶化，可能会不断出现错误并且难以预测。在内存使用量与时间之间建立映射的时间线将揭示泄漏的严重程度。一条精细的时间线 —— 比如，从函数到函数 —— 将进一步指出泄漏源。  
  
Xdebug 可以提供一条详细的时间线进行执行跟踪。当跟踪被启用后，Xdebug 将记录所有函数调用，包括每个函数的参数和返回值。您可以将每个日志或跟踪 的格式设为符合人类阅读习惯或者机器可读的格式。您最好使用前者，虽然您可能编写独立而特定的应用程序来分析后者。  
  
同转储一样，Xdebug 有若干个 php.ini 选项用于自定义跟踪内容。例如，下面一批设置将生成最详细的输出。  
  
xdebug.trace_format = 0  
xdebug.auto_trace = On  
xdebug.trace_output_dir=&quot;D:/web_server/xdebug/tracelog&quot;
xdebug.trace_output_name = trace.%c.%p  
  
xdebug.collect_params = 4  
xdebug.collect_includes = On  
xdebug.collect_return = On  
xdebug.show_mem_delta = On  
  
设定 xdebug.auto_trace = 1 将在执行所有 PHP 脚本之前先启用自动跟踪。另外，您可以通过代码设定 xdebug.auto_trace = 0，并分别使用 xdebug_start_trace() 和 xdebug_stop_trace() 函数启用和禁用跟踪。但是，如果 xdebug.auto_trace 为 1，则可以在包括配置好的 auto_prepend_file 之前先启动跟踪。  
  
选项 xdebug.trace_ouput_dir 和 xdebug.trace_output_name 用于控制保存跟踪输出的位置。在这里，所有文件都被保存到 /tmp/traces 中，并且每个跟踪文件都以 trace 为开头，后接 PHP 脚本的名称（%s）以及进程 ID（%p）。所有 Xdebug 跟踪文件都以 .xt 后缀结尾。  
  
默认情况下，Xdebug 将显示时间、内存使用量、函数名和函数调用深度字段。如果将 xdebug.trace_format 设为 0，则输出将符合人类阅读习惯（将参数设为 1 则为机器可读格式）。此外，如果指定 xdebug.show_mem_delta = 1，则可以查看内存使用量是在增加还是在减少，而如果指定 xdebug.collect_params = 4，则可以查看传入参数的类型和值。要监视每个函数返回的值，请设定 xdebug.collect_return = 1。  
*/
</pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mysql一些细节性的优化</title>
		<link>https://www.mudbest.com/mysql%e4%b8%80%e4%ba%9b%e7%bb%86%e8%8a%82%e6%80%a7%e7%9a%84%e4%bc%98%e5%8c%96/</link>
		
		<dc:creator><![CDATA[hkshadow]]></dc:creator>
		<pubDate>Fri, 19 Oct 2012 06:15:48 +0000</pubDate>
				<category><![CDATA[Mysql]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[最优]]></category>
		<guid isPermaLink="false">http://www.mudbest.com/?p=1586</guid>

					<description><![CDATA[1、对查询进行优化，应尽量避免全表扫描，首先应考虑在 where 及 order by 涉及的列上建立索引。  ... <a title="Mysql一些细节性的优化" class="read-more" href="https://www.mudbest.com/mysql%e4%b8%80%e4%ba%9b%e7%bb%86%e8%8a%82%e6%80%a7%e7%9a%84%e4%bc%98%e5%8c%96/" aria-label="阅读 Mysql一些细节性的优化">阅读更多</a>]]></description>
										<content:encoded><![CDATA[<p>1、对查询进行优化，应尽量避免全表扫描，首先应考虑在 where 及 order by 涉及的列上建立索引。</p>
<p>2、应尽量避免在 where 子句中对字段进行 null 值判断，否则将导致引擎放弃使用索引而进行全表扫描，如：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num is null
</pre>
<p>可以在num上设置默认值0，确保表中num列没有null值，然后这样查询：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num=0
</pre>
<p>3、应尽量避免在 where 子句中使用!=或<>操作符，否则<span id="more-1586"></span>将引擎放弃使用索引而进行全表扫描。</p>
<p>4、应尽量避免在 where 子句中使用 or 来连接条件，否则将导致引擎放弃使用索引而进行全表扫描，如：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num=10 or num=20
</pre>
<p>可以这样查询：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num=10
union all
select id from t where num=20
</pre>
<p>5、in 和 not in 也要慎用，否则会导致全表扫描，如：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num in(1,2,3)
</pre>
<p>对于连续的数值，能用 between 就不要用 in 了：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num between 1 and 3
</pre>
<p>6、下面的查询也将导致全表扫描：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where name like '%abc%'
</pre>
<p>若要提高效率，可以考虑全文检索。</p>
<p>7、如果在 where 子句中使用参数，也会导致全表扫描。因为SQL只有在运行时才会解析局部变量，但优化程序不能将访问计划的选择推迟到运行时；它必须在编译时进行选择。然而，如果在编译时建立访问计划，变量的值还是未知的，因而无法作为索引选择的输入项。如下面语句将进行全表扫描：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num=@num 
#&lt;mailto:num=@num&gt;
</pre>
<p>可以改为强制查询使用索引：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t with(index(索引名)) where num=@num 
#&lt;mailto:num=@num&gt;
</pre>
<p>8、应尽量避免在 where 子句中对字段进行表达式操作，这将导致引擎放弃使用索引而进行全表扫描。如：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num/2=100
</pre>
<p>应改为:</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where num=100*2
</pre>
<p>9、应尽量避免在where子句中对字段进行函数操作，这将导致引擎放弃使用索引而进行全表扫描。如：</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where substring(name,1,3)='abc'
#-name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30') = 0 
#-'005-11-30'生成的id
</pre>
<p>应改为:</p>
<pre class="brush: sql; title: ; notranslate">
select id from t where name like 'abc%'
select id from t where createdate &gt;= '2005-11-30' and createdate &lt; '2005-12-1'
</pre>
<p>10、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算，否则系统将可能无法正确使用索引。</p>
<p>11、在使用索引字段作为条件时，如果该索引是复合索引，那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引，否则该索引将不会被使用，并且应尽可能的让字段顺序与索引顺序相一致。</p>
<p>12、不要写一些没有意义的查询，如需要生成一个空表结构：</p>
<pre class="brush: sql; title: ; notranslate">
select col1,col2 into #t from t where 1=0
</pre>
<p>这类代码不会返回任何结果集，但是会消耗系统资源的，应改成这样：</p>
<pre class="brush: sql; title: ; notranslate">
create table #t(…)
</pre>
<p>13、很多时候用 exists 代替 in 是一个好的选择：</p>
<pre class="brush: sql; title: ; notranslate">
select num from a where num in(select num from b)
</pre>
<p>用下面的语句替换：</p>
<pre class="brush: sql; title: ; notranslate">
select num from a where exists(select 1 from b where num=a.num)
</pre>
<p>14、并不是所有索引对查询都有效，SQL是根据表中数据来进行查询优化的，当索引列有大量数据重复时，SQL查询可能不会去利用索引，如一表中有字段sex，male、female几乎各一半，那么即使在sex上建了索引也对查询效率起不了作用。</p>
<p>15、索引并不是越多越好，索引固然可以提高相应的 select 的效率，但同时也降低了 insert 及 update 的效率，因为 insert 或 update 时有可能会重建索引，所以怎样建索引需要慎重考虑，视具体情况而定。一个表的索引数最好不要超过6个，若太多则应考虑一些不常使用到的列上建的索引是否有必要。</p>
<p>16、应尽可能的避免更新 clustered 索引数据列，因为 clustered 索引数据列的顺序就是表记录的物理存储顺序，一旦该列值改变将导致整个表记录的顺序的调整，会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列，那么需要考虑是否应将该索引建为 clustered 索引。</p>
<p>17、尽量使用数字型字段，若只含数值信息的字段尽量不要设计为字符型，这会降低查询和连接的性能，并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符，而对于数字型而言只需要比较一次就够了。</p>
<p>18、尽可能的使用 varchar/nvarchar 代替 char/nchar ，因为首先变长字段存储空间小，可以节省存储空间，其次对于查询来说，在一个相对较小的字段内搜索效率显然要高些。</p>
<p>19、任何地方都不要使用 select * from t ，用具体的字段列表代替“*”，不要返回用不到的任何字段。</p>
<p>20、尽量使用表变量来代替临时表。如果表变量包含大量数据，请注意索引非常有限（只有主键索引）。</p>
<p>21、避免频繁创建和删除临时表，以减少系统表资源的消耗。</p>
<p>22、临时表并不是不可使用，适当地使用它们可以使某些例程更有效，例如，当需要重复引用大型表或常用表中的某个数据集时。但是，对于一次性事件，最好使用导出表。</p>
<p>23、在新建临时表时，如果一次性插入数据量很大，那么可以使用 select into 代替 create table，避免造成大量 log ，以提高速度；如果数据量不大，为了缓和系统表的资源，应先create table，然后insert。</p>
<p>24、如果使用到了临时表，在存储过程的最后务必将所有的临时表显式删除，先 truncate table ，然后 drop table ，这样可以避免系统表的较长时间锁定。</p>
<p>25、尽量避免使用游标，因为游标的效率较差，如果游标操作的数据超过1万行，那么就应该考虑改写。</p>
<p>26、使用基于游标的方法或临时表方法之前，应先寻找基于集的解决方案来解决问题，基于集的方法通常更有效。</p>
<p>27、与临时表一样，游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法，尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许，基于游标的方法和基于集的方法都可以尝试一下，看哪一种方法的效果更好。</p>
<p>28、在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ，在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。</p>
<p>29、尽量避免大事务操作，提高系统并发能力。</p>
<p>30、尽量避免向客户端返回大数据量，若数据量过大，应该考虑相应需求是否合理。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PHP计算页面执行时间函数</title>
		<link>https://www.mudbest.com/php%e8%ae%a1%e7%ae%97%e9%a1%b5%e9%9d%a2%e6%89%a7%e8%a1%8c%e6%97%b6%e9%97%b4%e5%87%bd%e6%95%b0/</link>
		
		<dc:creator><![CDATA[hkshadow]]></dc:creator>
		<pubDate>Sun, 07 Oct 2012 06:11:47 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[微妙]]></category>
		<category><![CDATA[执行时间]]></category>
		<category><![CDATA[脚本]]></category>
		<guid isPermaLink="false">http://www.mudbest.com/?p=1542</guid>

					<description><![CDATA[很多时候想要知道脚本效率时间，这时候就需要知道脚本的运行时间，然后去优化它。可能有些人看到了Discuz页面底 ... <a title="PHP计算页面执行时间函数" class="read-more" href="https://www.mudbest.com/php%e8%ae%a1%e7%ae%97%e9%a1%b5%e9%9d%a2%e6%89%a7%e8%a1%8c%e6%97%b6%e9%97%b4%e5%87%bd%e6%95%b0/" aria-label="阅读 PHP计算页面执行时间函数">阅读更多</a>]]></description>
										<content:encoded><![CDATA[<p>很多时候想要知道脚本效率时间，这时候就需要知道脚本的运行时间，然后去优化它。可能有些人看到了Discuz页面底部也会有一个“Processed in 0.030282 second(s)&#8230;”这样的提示，对，这就是脚本执行时间。</p>
<p>如何计算一段php程序代码的执行消耗时间？</p>
<p>对于系统时间,可能很多programmer对php的time()函数并不陌生,可惜time()函数只返回,自从 Unix 纪元（格林威治时间 1970 年 1 月 1 日 00:00:00）到当前时间的秒数。<br />
没错,是秒.我们一段php程序代码执行耗时可能并不超过一秒,所以time()并不适用。<span id="more-1542"></span></p>
<p>php提供了一个更为精确的时间函数microtime():</p>
<p>microtime — 返回当前 Unix 时间戳和微秒数。</p>
<p>格式: mixed microtime ([ bool $get_as_float ] )</p>
<p>函数以 “msec sec” 的格式返回一个字符串,sec 是自 Unix 纪元（0:00:00 January 1, 1970 GMT）起到现在的秒数，msec 是微秒部分。<br />
如果输入参数为true,microtime() 将返回一个浮点数。</p>
<p>好了，然后的事情很简单，为了免于对返回的结果做复杂的字符串转换，我们设定microtime()输入参数为true，使得其返回的结果为浮点数。<br />
然后在程序开始和结束分别计算一次，两次结果相减便是程序执行的时间。(PHP手册里有一句话：永远不要比较两个浮点数是否相等。 )<br />
最后使用number_format格式化浮点数。此方法仅供测试，结果不一定精确。</p>
<p>Example #1 number_format() Example：</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$number = 1234.56;

// english notation (default)
$english_format_number = number_format($number);
// 1,235

// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56

$number = 1234.5678;

// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
?&gt;
</pre>
<p>Example #1 用 microtime() 对脚本的运行计时</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
/**
 * Simple function to replicate PHP 5 behaviour
 */
function microtime_float() {
	list ( $usec, $sec ) = explode ( &quot; &quot;, microtime () );
	return (( float ) $usec + ( float ) $sec);
}

$time_start = microtime_float ();

// Sleep for a while
usleep ( 100 );

$time_end = microtime_float ();
$time = $time_end - $time_start;

echo &quot;Did nothing in $time seconds\n&quot;;
?&gt;
</pre>
<p>类：</p>
<pre class="brush: php; title: ; notranslate">
&lt;?
/**
 * 页面执行时间计算
 * @author hkshadow
 */
class RunTime//页面执行时间类
{
	private $starttime;//页面开始执行时间
	private $stoptime;//页面结束执行时间
	private $spendtime;//页面执行花费时间
	function getmicrotime()//获取返回当前微秒数的浮点数
	{
		list($usec,$sec)=explode(&quot; &quot;,microtime());
		return ((float)$usec + (float)$sec);
	}
	function start()//页面开始执行函数，返回开始页面执行的时间
	{
		$this-&gt;starttime=$this-&gt;getmicrotime();
	}
	function end()//显示页面执行的时间
	{
		$this-&gt;stoptime=$this-&gt;getmicrotime();
		$this-&gt;spendtime= $this-&gt;stoptime - $this-&gt;starttime;
	}
	function display()
	{
		$this-&gt;end();
		echo &quot;&lt;p&gt;运行时间：&quot;.number_format($this-&gt;spendtime,10).&quot;秒&lt;/p&gt;&quot;;
	}
}

$timer=new Runtime();
$timer-&gt;start();  //执行脚本开始时间 
$timer-&gt;display(); //显示页面(脚本执行结束时间)
?&gt;
</pre>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
