- 分布式数据库处理的是分布式关系运算,其SQL的优化方法与单机关系数据库有所不同,侧重考虑的分布式环境中的网络开销。分布式执行计划中,应该尽量将SQL中的运算下推到底层各个节点执行,避免跨节点运算,从而减少网络开销、提升SQL执行效率。
explain select id,accountno from account where userid=2;EXPLAIN指令的执行结果包括语句下发的节点,实际下发的SQL语句和数据的合并操作的信息。这些信息是系统静态分析产生的,并没有真正的执行语句。 通过EXPLAIN2命令可查看指定节点上的执行计划。如:
explain2 datanode=dn1 sql=select id,accountno from account where userid=2;explain2会将sql语句加上explain下发到指定的datanode执行,并把节点上explain的结果返回调用者。
对于SQL优化有以下原则:
- SQL语句中尽可能带有拆分字段,并且拆分字段过滤条件的取值范围越小,越有助于提高查询速度。在数据写入时,必须给拆分字段赋值。
- 拆分字段的查询条件尽可能是等值条件。
- 如果拆分字段的条件是IN子句,则IN后面的值的数目应尽可能少。特别注意,随着业务增长,某些IN子句的条件会随之增长。
- 如果SQL语句不带有拆分字段,那么DISTINCT、GROUP BY和ORDER BY在同一个SQL语句中尽量只出现一种。
- 数据查询时,应该尽量减少节点返回的结果数量,这样能够使消耗的网络带宽最小,使查询性能能够达到最优状态。
跨节点查询通常发生在下列语句中:
- 涉及多个分片的分布式 Join;
- 涉及多个分片的聚合函数;
- 复杂子查询。
这些语句可以通过以下策略来优化:
- 合理调整查询语句,使查询条件中包含拆分字段的等值条件,这样就能够将语句下推到单一节点执行。
- 参与Join的表配置相同的拆分规则,查询时将拆分字段作为Join的关联条件,这样Join操作就可以在节点内完成。
- 将参与Join的表中数据量较小的表配置成全局表,通过数据冗余避免跨节点。
- 如果一定需要跨节点Join,尽量对驱动表添加更多的过滤条件,从而使参与跨节点Join的数据量尽可能的少。
- 如果查询涉及到了多个节点,则尽量不要使用limit a,b这样的子句
- GROUP子句尽量包含拆分字段。
- 对语句进行改写,将复杂子查询分解为多条语句来执行。
- 子查询尽可能改写成Join的形式。