本文介绍网络问题对数据库性能的影响。
前端协议
- 简单查询:一个简单查询周期是由前端发送一条Query消息给后端进行初始化开始。这条消息包含一个用文本字符串表达SQL命令(或者一些命令)。后端根据查询命令串的内容发送一条或者更多条响应消息给前端,并且最后是一条ReadyForQuery响应消息。
- 扩展查询:在扩展协议里,前端首先发送一个Parse消息,它包含一个文本查询字符串,如果成功创建了一个命名的预备语句对象,那么它将持续到当前会话结束,一旦一个预备语句存在,就可以很使用Bind消息使之进入执行状态,Bind消息会传递相关参数,如果该语句被反复执行,服务器可能会保存创建好的计划并在后续对同一个预备语句的Bind消息中重用。之后可以用一个Execute消息执行它。最后会发出表示源SQL命令结束的CommandComplete消息。
网络延迟不同引起的性能差异
- Ping延迟1毫秒,1000条插入耗时4000毫秒。
- Ping延迟0.1毫秒,1000条插入耗时500毫秒。
在插入数据时进行网络抓包,网络包示例如下。
- 在网络包中搜索
tcpdump -i eth0 port 3433 -s 0 -w t.cap
。 - B代表bind(绑定);D代表Describe(描述);E代表execute(执行)。
- C代表command complete(命令完成)。
通过以上测试可以得出如下结论:
- 结论:
单行插入1条网络消耗时间就达到2毫秒,1000条INSERT语句,消耗在网络的响应时间(RT)就达到2秒。
- 解法:
使用
insert into values(),(),()
的方式批量进行发送,避免网络的多次交互。