系统Model底层隐藏的坑
前段时间实现某一个功能,涉及到对数据表的查询操作,经本地与测试环境测试过后都没问题,这一过程貌似都很顺利,想想是不是要下班了啦(虽然时间好像也不早了),接着推入正式环境下进行最后的测试(心想应该不会有什么问题吧,毕竟就只是对数据的查询,而且都已经测试过了,数据也完好的输出);
最后….终于还是意想不到的事情发生了。。。
产品那边说为何为何这么慢,数据加载不出来。。。
根据产品那边的反馈,我看了看相关程序,觉得应该没问题呀,再看看表字段设计,发现了我加的那几个字段有的应该要加上索引的但我没加,加上去了,测试下还是几乎一样慢,几乎数据加载不来。。。
再看了看测试环境下的一些配置文件与正式环境下的配置对比,也没发现什么问题呀,
找问题。。。。
(这时思维貌似是陷进了某个死角。。)
经过主管的细心排查终于发现问题出现在哪里了。。。
原来是Model底层有个包含所有表名其主键的一个缓存文件搞的鬼(好像是程序执行时没加载到进行,或者保存的时候没保存成功到该缓存文件),导致程序每一次涉及到对表的操作是都是重新去服务器里去查询所有表,想想多可怕啊。。。
总结这个事情反应出了以下问题:
1.程序方面的逻辑判断不够严谨!
体现在如果以上的那个缓存文件加载失败,或者数据保存到缓存文件不成功,在日志里能够体现出来,那是不是定位问题所产生的原因是不是更快、更精准了!
2.排查问题的思维方式太过于局限性!
貌似总是在一个层面上去思考问题,很难跳出当前的思维模式站在其它的角度去思考问题,这可能是自身的问题!(思维不够灵活,或者说经验不足)
3.对系统底层框架的实现原理不够深入!
可能在日常的开发中比较繁忙,我们只是停留在使用某一个方法,并没有去深入了解它的底层实现原理,
这样的话出现问题了,搞的就比较被动!
对于以上总结可能还远远不够,但重要的是一定要去阅读源代码!
代码片段:
/** * 生成表结构信息 * * @param string $table * @return */ public function tableInfo($table) { if (empty($table)) return false; //只取主键,find(2)等自动匹配主键时使用 if (file_exists(BASE_DATA_PATH . '/cache/fields/_pk.php')) { $this->fields = require(BASE_DATA_PATH . '/cache/fields/_pk.php'); } else { $full_table = Db::showTables(); $_pk_array = array(); $count = strlen(C('tablepre')); foreach ($full_table as $v_table) { $v = array_values($v_table); if (substr($v[0], 0, $count) != C('tablepre')) continue; $tb = str_replace(C('tablepre'), '', $v[0]); $fields = DB::showColumns($tb); foreach ((array) $fields as $k => $v) { if ($v['primary']) { $_pk_array[$tb] = $k; break; } } } $this->fields = $_pk_array; F('_pk', $_pk_array, 'cache/fields'); } return $this->fields[$table]; }