插入数据:
批量插入 手动提交事务 主键顺序插入性能高于乱序插入
大批量插入数据,可以使用MySQL数据库提供的load指令进行插入:
Load指令:
#在连接服务器时,加上参数 --local-infile 表示读取本地文件。
mysql --local-infile -u root -p
#设置全局参数local_infile为1,开启从本地加载文件导入的开关。
set global local_infile = 1;
#执行load指令将准备好的数据,加载到表结构中。
load data local infile 'path/to/file' into table [table_name] fields terminated by '[separator]' lines terminated by '\n';
用Load指令将本地文件导入数据库,速度会比insert语句快。

主键优化:
数据组织方式 在InnoDB中,表数据是根据主键顺序存放,这种存储方式的表称为聚集索引,(索引组织表)。
InnoDB的逻辑存储结构为 Tablespace – Segment – Extent – Page – Row
页分裂
基于聚集索引的表插入新行,或主键更新导致需要移动行的时候,可能会出现“页分裂”问题。
当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次页分裂操作。页分裂操作会导致表占用更多的磁盘空间。
所以当主键写入时乱序时,InnoDB不得不频繁的做页分裂操作,以便为新的行分配空间。页分裂会导致大量移动数据,一次插入最少需要修改三个页而不是一个页。
页合并
当删除一行记录时,实际上该记录只是被标记为删除,并且它的空间变得允许被其他记录声明使用。 当页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页,查看是否可以合并优化空间利用。
主键设计原则
满足业务需求的情况下,尽量降低主键的长度。 插入数据时,尽量选择顺序插入,选择 AUTO_INCREMENT 自增主键 尽量不要使用UUID做主键或者是其他自然主键(身份证) 业务操作时,尽量避免对主键的修改。
order by 优化
filesort排序方式
在排序缓冲区sort buffer中完成排序操作。
index排序方式
通过有序的索引直接返回有序数据,操作效率高。

使用联合索引时,需要满足最左前缀法则。

在对带有联合索引的字段进行order by排序时,对字段1升序,字段2降序。也会使用filesort排序。

在创建索引时,需要指定排序方式。
// 该联合索引可以用 a asc/desc, b desc/asc 的order by排序
create index idx1 on t1(a asc , b desc);

order by优化原则
根据排序字段建立合适的索引,多字段排序时,遵循最左前缀法则。 实现覆盖索引 多字段排序时,要注意联合索引的创建规则(ASC / DESC)。
出现不可避免的filesort时,为防止缓冲区溢出,可以修改缓冲区大小。 使用 set sort_buffer_size = [num] 完成。
group by优化:
使用group by时,对分组字段创建联合索引。 不满足最左前缀法则,索引失效会导致SQL低性能问题。
limit优化:
在大数据量情况下,搜索位置越靠后性能越低。 前缀数据都会被丢弃。
// 访问的位置越靠后,查询速度越慢。
select * from t1 limit st,num;
可以使用覆盖索引+子查询的方式进行优化
select * from table1 t1 , (select id from table1 order by id limit 9000000,10) temp where temp.id = t1.id;
count优化:
count() 是一个聚合函数,对于返回的结果集逐行判断,最后返回累计值。
MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回数据,效率很高。
InnoDB引擎执行count(*)时,需要累积计数,效率并不高。
count类型:
count(主键)
InnoDB引擎会遍历整张表,将每一行的主键id都返回给服务层,服务层接收到主键后,计数+1。
count(字段)
没有not null约束:InnoDB会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。 有not null约束:InnoDB引擎同样会会将数据返回给服务层,服务层按行进行累加。
count(常数)
InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,标记一个常数,按行进行累加。
count(*)
InnoDB并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。
count优化原则
效率由高到低 count(*) ≈ count(常数) > count(主键) > count(字段)
尽量使用count(*),数据库专门做了优化。
update优化:
如果字段没有索引,SQL语句就会上表锁 所以尽量对有索引的字段作为条件执行SQL语句,避免表锁导致性能下降。
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。
如果索引失效,行锁会升级为表锁。
小结:
插入数据优化: 如果需要保存多条数据,批量插入,手动控制事务、主键顺序插入 大批量插入时,可以通过加载本地文件的方式构建表。
主键优化: 主键是乱序插入时,可能出现页分裂问题,一个操作可能会对几个页同时操作。 主键长度尽量短,顺序插入
order by优化: using index:通过索引返回数据、性能高 尽量使用覆盖索引,创建联合索引时,要考虑索引的字段顺序和排序方式。
group by优化: 多字段分组时,不满足最左前缀法则,会导致索引失效。 尽量覆盖索引。
limit优化: 访问的数据越靠后,查询速度越低 覆盖索引+子查询优化
count优化: 使用count(*)优化 或是自行计数,存储在专门的表中。
update优化: 写操作,覆盖索引,根据主键/索引字段来进行操作 避免表锁,导致数据库的并发性能下降。