2024年4月27日发(作者:)
0 设计原则
任何语句使用前explain看执行计划是否用到索引
不要从明细表查统计结果,定期统计插入到汇总表
禁止使用SELECT *,必须指定字段名称,包括insert table后边加字段列表
明细统计时,只统计编码,不要关联名称等冗余字段
联合查询时,每个表必须加别名以提高SQL解析效率,如 SELECT FROM GS T1 LEFT JOIN
GSJJ T2 ON =
每个查询结果集使用的内存量不要超过256M,可以通过时间范围控制,如 RK BETWEEN A
AND B,建议大表按可小时操作
页面查询在10秒内要返回结果,服务器超时限制默认为65秒 (查看query cache是否足够
大和命中率,show variables like '%cache%');
语句中避免子查询,子查询无法使用索引
语句中避免使用 GROUP BY, 可通过批量程序定期汇总
1 字段设计
尽可能使用更小的数据类型,如 TINYINT、smallint,MEDIUMINT、INT、BIGINT (如int(11)的
11代表客户端显示宽度,并不是取值范围,tinyint -2^8-2^8-1,smallint -2^15-2^15-1 int
-2^31-2^31-1 bigint -2^63-2^63-1)
尽量少用 TEXT、BLOB 等专有类型 (用链接代替)
字符型,数值型字段类型不能混合使用,依赖后期转换
相同字段不同表中的类型和长度要一致
字段名称不能使用关键字
不要指定字段级编码,建议全库统一
默认值要规范,例如日期不要使用 0000-00-00
2 索引使用
一般情况下,一次查询只会用到一个索引 (特定情况出现merge index的情况,如下可能出现
(a=1 or b=2)会合并a和b的索引,或者使用union all)
每个表索引越少越好,建议1-3个,最多5个 (oltp 1-5,olap 5以上)
每个查询必须用到索引 (小表可能全表更好,视数据量决定)
建立组合索引时,WHERE 条件中用到等于的字段放前边,用到范围的字段放后边,如
DD=100000 AND SJ BETWEEN A AND B 例子(见以上)
删除重复字段的索引,减少dml IO
索引中重复的记录数越少,效率越高,效率最高的是主键 (如果同一记录超过50%,全表扫
描定期analyze table收集统计信息和直方图,如果可以加not null或者unique的最好加上)
索引字段最好不要存在 NULL,NULL可用 0 替代,建议把默认值设置为 0 (也可以
myisam_stats_method和innodb_stats_method取值nulls_equal,在null远多于非null的情况
下,建议表设计 default 0)
组合索引可以只使用第一个,或者前两个,或者前几个,不能从第二个开始用,也不能跳着
使用 (索引使用从前缀开始,多字段索引到between或者<,>等以后字段不会使用,排序最好
在索引中实现)
3 查询条件
SQL 语句的 WHERE 条件避免无效条件和无效括号,如 SELECT BM FROM GS WHERE (1=1) 、
order by
SQL语句中不要加用不到的排序
WHERE 条件中 最好不要用 IN 和 LIKE
WHERE 条件中不要使用 NOW() 等进行判断,影响执行计划
索引要使用的字段不要使用函数或者进行运算,如 field1 + 1 = field2、adddate(field1,…、CAST
禁止字段格式转换,如 SELECT * FROM GS WHERE BM=200000,数值两边不要加引号 (大多
数字段使用函数不会使用索引,只有形如left(BM)='200000'等可以使用)
4 存储过程
存储过程中操作的记录数超过1000条时不能使用游标 (禁止游标,用临时表代替)
在存储过程的关键步骤开始和结束都要记录信息到日志表,用于监控和调试
字符变量使用单引号,不要使用双引号,【"2012-09-23 00:00:00"】 可改为 【'2012-09-23
00:00:00'】
存储过程要能够重复执行,执行时需要清空历史冲突记录
5 远程表
远程表结构要与原始表一致,尤其是索引
远程表数据不要大于256M,远程表的 WHERE 无效
远程表一般用来全表小数据全量同步
6 查询技巧
SQL语句不要太长,如果 IN 列表太多必须改为 LEFT JOIN , 且关联字段主键索引
避免使用 LIKE,【lrsj like "2012-09-23%"】 可改为 【LRSJ BETWEEN '2012-09-23 00:00:00' AND
'2012-09-23 23:59:59'】或者left,right函数
WHERE 多个OR条件不走一个索引时可通过 UNION,如【bm1=953016 or bm2=953016】改
为【SELECT … WHERE BM1=953016 UNION ALL SELECT … WHERE BM2=953016】(merge
index,explain的结果是using union(idx_name,idx_name))
7 性能优化
编译器改为ICC可以提升5%,文件格式改为XFS可以提升5%,增加1/6磁盘可以提升1/6,
优化索引和结构一般可以提升100-1000倍
使用type=heap的临时表
8 引擎使用
innodb引擎,在过程结尾提交,避免过度commit
9 权限控制
PHP连接MYSQL的用户只分配SIUD权限


发布评论