1.不在索引列进行数学运算或凼数运算
- 无法使用索引
- 导致全表扫描
2.拒绝大SQL,拆解成多条简单SQL
- 简单SQL缓存命中率更高
- 减少锁表时间,特别是MyISAM
- 用上多CPU
优先使用ENUM或SET
- 字符串
- 可能值已知且有限
存储
- ENUM占用1字节,转为数值运算
- SET视节点定,最多占用8字节
- ==比较时需要加‘ 单引号(即使是数值)==
`sex` enum('F','M') COMMENT '性别'
`c1` enum('0','1','2','3') COMMENT '职介审核'
3. 改写OR为IN()
注意控制IN的个数,建议n小亍200
4.改写OR为UNION
Select * from opp WHERE phone='010-88886666' or
cellPhone='13800138000';
改为:
Select * from opp WHERE phone='010-88886666'
union
Select * from opp WHERE cellPhone='13800138000';
5.避免 % 前缀模糊查询
- B+ Tree
- 使用不了索引
- 导致全表扫描
6.同数据类型的列值比较
字段:`remark` varchar(50) NOT NULL COMMENT '备注,
默认为空',
MySQL>SELECT `id`, `gift_code` FROM gift WHERE
`deal_id` = 640 AND remark=115127;
1 row in set (0.14 sec)
MySQL>SELECT `id`, `gift_code` FROM pool_gift WHERE
`deal_id` = 640 AND remark= ' 115127 ' ;
1 row in set (0.005 sec)
避免使用NULL字段
- 很难进行查询优化
- NULL列加索引,需要额外空间
- 含NULL复合索引无效
少用并拆分TEXT/BLOB
TEXT类型处理性能远低亍VARCHAR
- 强制生成硬盘临时表
- 浪费更多空间
- VARCHAR(65535)==>64K (注意UTF-8)
- 尽量不用TEXT/BLOB数据类型
- 若必须使用则拆分到单独的表
CREATE TABLE t1 (
id INT NOT NULL AUTO_INCREMENT,
data text NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
字符字段必须建前缀索引
`pinyin` varchar(100) DEFAULT NULL COMMENT '小区拼音',
KEY `idx_pinyin` (`pinyin`(8)),
) ENGINE=InnoDB
拒绝大SQL,拆解成多条简单SQL
- 简单SQL缓存命中率更高
- 减少锁表时间,特别是MyISAM
- 用上多CPU
统一命名规范
- 库表等名称统一用小写
- 索引命名默认为“idx_字段名”
- 库名用缩写,尽量在2~7个字母
- 避免用保留字命名