轻量应用服务器 SQL 使用规范建议

这篇总结了腾讯云轻量数据库服务的SQL使用规范,涵盖数据库设计、查询、开发及索引设计,强调避免大事务、使用UTF8编码、优化查询效率,并推荐使用explain分析执行计划。 – 数据库设计:所有字符存储使用UTF8/UTF8MB4,避免大事务。 – 查询规范:优先利用索引优化order by/group by,减少join表数。 – 开发规范:拆分复杂SQL,避免外键和存储过程,使用批量插入。

相关产品
轻量应用服务器 产品页,含版本规格、价格与购买入口。

这里说明在创建轻量数据库服务后的 SQL 使用规范建议。

一、数据库基本设计规范

·所有的字符存储与表示,均以 UTF8 或者 UTF8MB4 编码,表和字段需要有注释信息。

·尽量避免使用大事务。

注意:说明:

注意:例如在一个事务里进行多个 select 或 update 语句,如果是高频事务,会严重影响 MySQL 并发能力,因为事务持有的锁等资源只在事务 rollback/commit 时才能释放。但同时也要评估数据写入的一致性。

二、数据库 SQL 查询规范

·当使用 order by … limit 查询时,优先考虑通过索引优化查询语句,提高执行效率。

·使用 order by、group by、distinct 执行查询时,where 条件过滤出来的结果集请保持在1000行以内,否则会降低查询效率。

·使用 order by、group by、distinct 语句时,优先利用索引检索排序好的数据。如 where a=1 order by b 可以利用 key(a,b)。

·使用 join 连接查询时,where 条件尽量充分利用同一表上的索引。

注意:说明:

注意:例如,select t1.a, t2.b from t1,t2 where t1.a=t2.a and t1.b=123 and t2.c=4。

注意:如果 t1.c 与 t2.c 字段相同,那么 t1上的索引 (b,c) 就只用到 b。此时如果把 where 条件中的 t2.c=4 改成 t1.c=4,那么可以用到完整的索引。这种情况可能会在字段冗余设计(反范式)时出现。

·使用 union all 不对数据去重,由于少了排序操作,速度快于使用 union,如果业务没有去重的需求,优先使用 union all,减少使用 union。

·在代码中实现分页查询逻辑时,若 count 为0应直接返回,避免执行后面的分页语句。

·避免频繁对表进行 count 操作。对大数据量表进行 count 操作耗时会较长,一般都是秒级响应速度。如果有频繁对表进行 count 操作的需求,请引入专门的计数表解决。

·确定返回结果只有一条时,使用 limit 1。在保证数据无误的前提下,可以确定结果集数量时,尽量使用 limit 查询,尽可能快速返回结果。

·评估 delete 和 update 语句效率时,可以将语句改成 select 后执行 explain(explain 命令可以帮助我们分析 SQL 查询语句的执行计划和性能瓶颈)。但需注意,如果频繁执行 select 语句会导致数据库性能慢,因此在使用 explain 命令分析 SQL 查询语句时,需尽量减少 select 语句的执行次数,在分析 SQL 查询语句时,需要综合考虑查询效率和数据库性能,权衡利弊,选择最优的方案。

·truncate table 比 delete 速度快,且使用的系统和日志资源少,如果删除的表上没有触发器,且进行全表删除,建议使用 truncate table。

注意:说明:

·尽量不要使用负向查询,避免全表扫描。

注意:说明:

注意:使用负向查询是指使用负向运算符,如:NOT, !=, <>, NOT EXISTS, NOT IN 以及 NOT LIKE 等。如果使用负向查询,无法利用索引结构做二分查找,只能做全表扫描。

·避免对三个表以上执行 join 连接。需要 join 的字段,数据类型必须保持一致。

·多表关联查询时,保证被关联的字段需要有索引;在多表 join 中,尽量选取结果集较小的表作为驱动表,用来 join 其他表。即使双表 join 也要关注表索引、SQL 性能情况。

三、数据库 SQL 开发规范

·对于简单 SQL,优先考虑拆分。

注意:说明:

注意:如 OR 条件:f_phone='10000' or f_mobile='10000',两个字段各自有索引,但只能用到其中一个。可以拆分成2个 SQL,或者使用 union all。

·需要在 SQL 中进行复杂的运算或业务逻辑时,优先考虑在业务层实现。

·使用合理的分页方式以提高分页效率,大页情况下不使用跳跃式分页。

注意:说明:

·在事务里使用更新语句时,尽量基于主键或 unique key,否则会产生间隙锁,内部扩大锁定范围,导致系统性能下降,产生死锁。

·尽量不使用外键与级联,外键概念在应用层处理。

注意:说明:

注意:例如,学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,则为级联更新。

·减少使用 in 操作,in 后的集合元素数量不超过500个。

·为了减少与数据库交互的次数,可以适度采用批量 SQL 语句。例如:insert into … values (xx),(xx),(xx)….(xx); 这里 xx 的个数建议100个以内。

·避免使用存储过程,存储过程难以调试和扩展,更没有移植性。

·避免使用触发器、事件调度器(event scheduler)和视图实现业务逻辑,这些业务逻辑应该在业务层处理,避免对数据库产生逻辑依赖。

·避免使用隐式类型转换。

注意:说明:

注意:类型转换规则具体如下:

·业务允许的情况下,事务里包含 SQL 语句越少越好,尽量不超过5个。因为过长的事务会导致锁数据较久,MySQL 内部缓存、连接消耗过多等问题。

·避免使用自然连接(natural join)。

注意:说明:

注意:自然连接没有显示定义连接列,而是隐含,会出现难以理解及无法移植问题。

四、数据库索引设计规范

·根据实际业务需求,减少使用无法利用索引优化的 order by 查询语句。order by、group by、distinct 这些语句较为耗费 CPU 资源。

·涉及到复杂 SQL 语句时,优先参考已有索引进行设计,通过执行 explain,查看执行计划,利用索引,增加更多查询限制条件。

·使用新的 select、update、delete 语句时,都需要通过 explain 查看执行计划中的索引使用情况,尽量避免 extra 列出现:Using File Sort,Using Temporary。当执行计划中扫描的行数超过1000时,需要评估是否允许上线。需每日进行慢日志统计分析,处理慢日志语句。

注意:说明:

注意:explain 解读:

·在 where 条件列上使用函数,会导致索引失效。

注意:说明:

注意:如 where left(name, 5) = 'zhang',left 函数会导致 name 上的索引失效。可在业务侧修改该条件,不使用函数。当返回结果集较小时,业务侧过滤满足条件的行。

赞 (0)
上一篇 5天前
下一篇 5天前