vlambda博客
学习文章列表

数据库优化一 :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 字段包括在索引当中减少排序,效率会更高