CI框架添加sql日志及优化记录

今天从第三方网站上检测到我们的资讯页打开速度比较慢,在优化之前同事的代码过程中的一些经验,记录下来方便自己回顾。

某个页面打开速度比较慢,首先查看了下mysql的慢查询日志,发现并没有记录,慢查询设置的是1S,说明单条sql的查询速度并没有很慢。然后就去检查CI的SQL日志,这里说下我们在CI框架中添加了所有的SQL执行日志(链接:缺),以备检查。

检查到某条SQL查询速度比较慢:

SELECT `exp_dnbiz_article`.* FROM (`exp_dnbiz_article`) JOIN `exp_dnbiz_article_type` AS t ON `exp_dnbiz_article`.`article_type_id`=`t`.`id`
WHERE `article_type_id` = ‘1’ AND `delete_status` = 1 AND `show_status` = ‘Is_show’ AND `article_type_id` != ‘6’
AND `t`.`parent_id` != ‘7’ AND `article_date` < ‘2018-04-04 13:38:48’ ORDER BY `article_date` DESC;

耗时:3.983s   查看索引又很快

而且没进慢日志查询,说明执行速度在1s以内,检查后发现是查询数据太大,导致传输速度慢,调整为查询只需要的字段,而不是* 后,查询效率明显提高。

总结针对字段存储字节比较大的数据,在查询时不要简单用*来查询全部,而是只查询要使用的字段即可。

然后寻找原因,为什么这里要查询这么多条数据处理,按照业务逻辑应该查询一条即可。找到代码截图如下:

发现用的是CI自己封装的辅助查询函数,但是这里是先查询出所有数据后取第一条,从而导致查询开销过大,速度较慢,如果只差1条,还是用limit0,1,而不是直接用CI的辅助查询方法,都是细节疏忽导致的。

附CI关于row()的辅助函数说明文档:

Nginx和PHP间的通信原理

今天在研究Nginx和PHP的通信原理,记录下作为自己的学习笔记。

首先来简单说一下,当访问我的blog时,访问的请求怎么在我的服务器上通信的:

 

这里我们看到nginx收到请求后,通过socket把不同进程间的数据通过FastCGI协议发送给相应的php-cgi进程,然后执行相应的操作。

CGI我们知道是通用网关协议,当webserver要访问PHP文件时,就要找PHP解析器来处理,但是nginx要传哪些参数给解析器,就是CGI来规定的,然后解析器还要去解析php.ini文件,进行初始化,然后处理请求,再以CGI规定的格式返回处理结果给webserver。

FastCGI则是一个常驻(long-live)的CGI,只有在启动初始化时,解析一次php.ini,初始化环境,提升效率。

php-cgi进程则是被php-fpm管理的对象,php-fpm全称为PHP FastCGI Process Manager,即php-fpm会根据用户配置来管理一批fastcgi进程,比如重启补全等,而真正衔接PHP和Nginx的则是fastcgi进程。

Nginx 作为我们常用的Webserver,以我的blog为例,我们看看是如何设置的。

我这里的socket采用的unix domain socket,因为nginx和php-fpm是在同一台服务器上,所以用本地套接字即可。

socket套接字主要有两种类型:unix domain socket和internet domain socket两种类型,简单说下他们的区别:

unix domain socket是进程间通信套接字,用于同一台主机上不同进程间交换数据。

intetnet domain socket网络套字节,是基于TCP/IP网络间的通信,nginx和php-fpm可以在不同的服务器上。也可以用于一台服务器,地址为本地127.0.0.1即可。

unix domain sokcket是用于同一台主机,不需要经过网络协议栈,不需要打包拆包、计算校验、维护应答等,只是将应用层数据从一个进程复制到另外一个进程,所以效率更快。而且不是用IP和端口表,是直接使用系统文件的地址来作为自己的身份,如上图所示。由于是在本机通过内核通信,不会丢包也不会出现发包次序和接收包次序不一致的问题。