数据库优化一 :sql优化核心
网上的大佬介绍的太多了,看得太累,简单总结一下
字段设计
价格使用定点数decimal
小单位大数额避免出现小数
单表字段不宜过多(最多30)
尽可能使用 not null
关联表的设计
一对多(使用外键)
多对多(单独新建一张表将多对多拆分成两个一对多)
一对一(如商品的基本信息(item)和商品的详细信息(item_intro),通常使用相同的主键或者增加一个外键字段(item_id))
范式
第一范式1NF:字段原子性(字段原子性,字段不可再分割。)
第二范式:消除对主键的部分依赖(即在表中加上一个与业务逻辑无关的字段作为主键)
第三范式:消除对主键的传递依赖(传递依赖:B字段依赖于A,C字段又依赖于B。比如上例中,任课老师是谁取决于是什么课,是什么课又取决于主键id。)
存储引擎选择
MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。
Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键保证数据完整性。比如OA自动化办公系统。
索引
通过explain查看适合加索引的字段
语法细节
字段要独立出现
like查询,不能以通配符开头
复合索引只对第一个字段有效
or,两边条件都有索引可用
查询缓存
在配置文件中开启缓存
windows上是my.ini,linux上是my.cnf
在[mysqld]段中配置query_***_type:
0:不开启
1:开启,默认缓存所有,需要在SQL语句中增加select sql-no-***提示来放弃缓存
2:开启,默认都不缓存,需要在SQL语句中增加select sql-***来主动缓存
更改配置后需要重启以使配置生效,重启后可通过show variables like ‘query_***_type’;来查看
在客户端设置缓存大小(通过配置项query_***_size来设置)
将查询结果缓存
分区
一般情况下我们创建的表对应一组存储文件,使用MyISAM存储引擎时是一个.MYI和.MYD文件,使用Innodb存储引擎时是一个.ibd和.frm(表结构)文件。
当数据量较大时(一般千万条记录级别以上),MySQL的性能就会开始下降,这时我们就需要将数据分散到多组存储文件,==保证其单个文件的执行效率==。
最常见的分区方案是按id分区,如下将id的哈希值对10取模将数据均匀分散到10个.ibd存储文件中:
create table article(
id int auto_increment PRIMARY KEY,
title varchar(64),
content text
)PARTITION by HASH(id) PARTITIONS 10
水平分割和垂直分割
水平分割:通过建立结构相同的几张表分别存储数据
垂直分割:将经常一起使用的字段放在一个单独的表中,分割后的表记录之间是一一对应关系。
集群
读写分离
负载均衡
典型SQL
select * 要少用
order by rand()不要用
使用exist 替代in
字段类型转换导致不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引导致全表扫描;
mysql 不支持函数转换,所以字段前面不能加函数,否则这将用不到索引
不要在字段前面加减运算
字符串比较长的可以考虑索引一部份减少索引文件大小,提高写入效率
like % 在前面用不到索引
根据联合索引的第二个及以后的字段单独查询用不到索引
排序请尽量使用升序
or 的查询尽量用 union 代替(Innodb)
复合索引高选择性的字段排在前面
order by / groupby 字段包括在索引当中减少排序,效率会更高