SELECT
- 【规则】SELECT语句中禁用通配符字段“*”。
使用通配符字段查询表时,如果因业务或数据库升级导致表结构发生变化,可能出现与业务语句不兼容的情况。因此业务应指明所需查询的表字段名称,避免使用通配符。
- 【规则】带有LIMIT的查询语句中必须带有ORDER BY保证有序。
作为一种分布式数据库,表数据将分布在多个DN上。如果SQL语句中只带有LIMIT,而不带有ORDER BY子句,数据库将会把网络传输较快的DN所发送的(符合查询要求的)结果作为最终结果输出到客户端。由于网络传输效率不同时刻可能发生改变,因此导致多次执行该SQL语句时,返回结果表现出不一致的情况。
- 【规则】避免对大字段(如VARCHAR(2000))执行ORDER BY、DISTINCT、GROUP BY、UNION等会引起排序的操作。
- 【规则】禁止使用LOCK TABLE语句加锁,仅允许使用 SELECT .. FOR UPDATE语句。
- 【建议】避免在SELECT目标列中使用子查询,可能导致计划无法下推到DN执行,影响执行性能。
- 【建议】考虑使用UNION ALL,少使用UNION,注意考虑去重。
- 【建议】避免频繁使用count()获取大表行数,该操作资源消耗较大,影响并行作业执行效率。
如果不需要实时的行数统计信息,可以尝试使用如下语句来获取表行数。
SELECT reltules FROM pg_class WHERE relname = 'tablename';
pg_class中所记录的表行数信息只在对该表执行ANALYZE以后才会更新。
目前ANALYZE有两种触发条件:
- 业务主动发送ANALYZE语句,例如:
--分析连接库中所有表 ANALYZE; --分析指定表 ANALYZE tablename;
- 借助AUTO VACUUM机制,在每间隔一定时间或表的增删达到一定行数时触发。间隔时间和增删比例可通过GUC参数设置。
- 业务主动发送ANALYZE语句,例如: