SQL优化
SQL优化插入数据
insert优化
批量插入
insert into tb_test 2values(1, 'Tom'), (2, 'Cat'), (3, 'jerry'); 手动提交事务
start transaction;
insert into test1 values(4, 'Tom'), (5, 'Cat'), (6, 'jerry');
insert into test1 values(7, 'Tom'), (8, 'Cat'), (9, 'jerry');
insert into test1 values(10, 'Tom'), (11, 'Cat'), (12, 'jerry');
commit; 主键序次插入
load大批量插入数据
#客户端链接服务端时,加上参数 --local-infile
mysql --local-infile -u root -p
#设置全局参数local-infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
#查看修改是否成功
select @@local_infile;
#执行local指令将准备好的数据,加载到表结构中
load data local infile './load_user_100w_sort.sql' into table tb_user fields terminated by ',' lines terminated by '\n';
主键优化
数据组织方式
在innoDB存储引擎中,表结构时根据主键序次组织存放的,这种存储方式的表称为索引组织表(IOT)https://i-blog.csdnimg.cn/direct/cac1f6f0288345cfb48031efa36ff09a.pnghttps://i-blog.csdnimg.cn/direct/b8a05104d8d94270abb48c1f96328b6a.png
页分裂
也可以为空,也可以添补一半,也可以添补100%,每个页包罗了2-N行数据(假如一行数据多大,会行溢出),根据主键排列
主键顺组插入:假如满了开辟一个新的页插入https://i-blog.csdnimg.cn/direct/df15e4fad2ab41d089a6d7029fe7adc1.png
主键乱序插入:首先找到1号数据页的50%位置,将其中 的一半移动到新的数据页,再插入新的数据到新的数据页后面,然后调解指针重新设计链表https://i-blog.csdnimg.cn/direct/28b9df20413c4c70a45cd75c6f338438.pnghttps://i-blog.csdnimg.cn/direct/81c4ee1580fb459faa7e1f1ad95e0a26.png
页合并
当删除一行记录时,实际上记录并没有被物理剔除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。https://i-blog.csdnimg.cn/direct/ddbb2ac25d5f4b1bb0058f4c47376b30.png
当页中删除的记录到达MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用https://i-blog.csdnimg.cn/direct/87347bb7e9d44f83a7d57125e02cacc2.png
MERGE_THRESHOLD:合并页的阈值,可以自己设置,在创建表或者创建索引时指定
主键设计原则
[*] 满意业务需求的情况下,尽量降低主键的长度
[*] 插入数据时,尽量选择序次插入,选择使用AUTO_INCREMENT自增主键
[*] 尽量不要使用UUID做主键或者是其他天然主键,如身份证号。
[*] 业务操作时,避免对主键的修改
order by优化
[*] Using filesort:通过表的索引或者全表扫描,读取满意条件的数据行,然后再排序缓冲区sort buffer中完成排序操作,所以不是通过索引直接返回排序效果的排序都叫FileSort排序。
[*] Using index:通过有序索引循序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
没有索引时,根据age,phone举行排序,
explain select id,age,phone from tb_user order by age, phone; 排序方式是用的filesorthttps://i-blog.csdnimg.cn/direct/5b4314845f2048a8b91d6a2432a64157.png
创建索引
create index idx_user_age_phone_aa on tb_user(age, phone); 再次排序可以看出使用的是index排序https://i-blog.csdnimg.cn/direct/3ce5f42154fc4a22aa850fe25c382c26.png
https://i-blog.csdnimg.cn/direct/c7e8de650a9d40d2a23f8c4fd48c8df0.png出现两种排序。
将使用的索引查询的主键序次换过来https://i-blog.csdnimg.cn/direct/a731781268f64124944dc2e463520ebe.png
一个正序一个倒序https://i-blog.csdnimg.cn/direct/f3aa5331c97c474384d2bfe91b532e0b.png
一升一降优化方式:
重新创建一个索引
create index idx_user_age_phone_ad on tb_user(age asc, phone desc); 注意
必须要查询的字段要覆盖到索引,用*不会使用索引https://i-blog.csdnimg.cn/direct/0cb0d047f2d344949eb7f4f4a74ebb86.png
总结
[*] 根据排序字段创建合适的索引,多字段排时,也遵顼最左前缀法则。
[*] 尽量使用覆盖索引
[*] 多字段排序时,一个升序一个降序,此时需要注意团结索引再创建时的规则(ASC/DESC)
[*] 假如不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k)
group by优化
未创建索引举行group by分组操作,可以看到未用到索引,temporary临时表性能比较低https://i-blog.csdnimg.cn/direct/245cf267887749f5ad9fdd971e8708d6.png
创建团结索引
create index idx_user_pro_age_sta on tb_user(profession, age, status); 当不满意最左前缀法则会让效率变低https://i-blog.csdnimg.cn/direct/70f5148fe0bb4ceaa125a0e47904a6b2.png
使用where也可以满意最左前缀法则https://i-blog.csdnimg.cn/direct/30d12f65aa544c94aecd9de0f62e3499.png
limit优化
问题
limit再大数据量的情况下,查询的数据越今后,所耗时越高
limit 2000000,10 ,此时需要mysql排序前2000010记录,仅仅返回2000000-20000010的记录,其他记录抛弃,查询排序的代价非常大。
优化
一样平常分页查询时,通过创建覆盖索引可以或许比较好得提高性能,可以通过覆盖索引子查询形式举行优化。
select * from tb_sku t, (select id from tb_sku order by id limit 20000000,10) a where t.id=a.id;
count优化
MyISAM引擎把一个表的总行数存在了磁盘上,因此实行count(*)的时间会直接返回这个数,效率很高,条件是没有where条件。
InoDB 引擎比较麻烦,实行count(*)时,需要把数据一行一行地从引擎里读取出来,然后累积技术。
优化思路
自己计数,比如借助redis等内存数据困维护记数
count()的几种方式
count是一个聚合函数,对于返回的效果集,一行一行地判断,假如count函数的参数不是NULL,累计值就加1,否则不加,末了返回累计值。
count(*)
不取值,直接累加
count(主键)
遍历整张表,把每一行的主键id值取出来,返回给服务层。服务层拿到主键后,直接按行举行累加(主键不可能为null)
count(字段)
没有not null约束:整张表的字段值取出来给服务层,判断是否为null,不为null,计数累加。
有not null约束:整张表的字段值取出来给服务直接计数累加。
count(1)
遍历整张表,不取值,服务层对于每一行放一个1进去,直接按行累加
update优化
注意
在更新,根据索引找到数据实行的是行锁,而不是索引找数据实行的是表锁。所以要根据索引找数据,否则并发性能降低。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]