内存数据库:速度快,成本高,索引:Map、平衡树、T树 ,应用Redis、Memchached
磁盘数据库:速度较快,成本适中(虚拟机,物理机),索引哈希,B+ ,应用:MySQL、Oracle
分布式数据库:速度较慢,容量大,存储:竖表、HDFS
SQL执行阶段
InnoDB引擎为什么要使用B+数据
1、每个节点(数据页)为16K,叶子节点存储数据。
2、多叉树,减少层高,减少IO,一般只需要3~4次IO即可。
3、叶子节点间存在顺序指针。
4、B+主索引存所有数据,B树辅助索引只存主键ID。
利用索引的好处是什么?
1、减少服务器扫描的数据量,提高查询效率
2、服务器避免排序和临时表
1、 没有建立索引
2、索引失效
select * from ShopTable where shopid > 10000000 VS where shopid > 50000000
虽然给shopid 加了一般索引,但执行where shopid > 10000000 没有使用到索引,回表(即从索引查出是哪一行,再回到表中取出所有字段返回)导致全表扫描当需要回表的数据量大于20%,MySQL会认为全表扫描会更快,故不走索引。
建议:
3 、使用索引不全面
where shopid > 234512 and update_days > -1 and buy_time > 300
只用到shopid的索引,索引效率低,查询到后还需要回表再过滤,导致效率严重下降
建议:
增加update_days 和 buy_time字段的索引
4、Order By /Group By /Distinct 避免临时表
避免不正确或低效的写法、避免复杂的SQL
1、limit 6000000 , 10
limit过大 ,limit A,B 会扫描 X+Y条数据,即当X过大时,扫描行数多导致慢查询
建议:
尽量使用id > xx LIMIT 10,建议分页遍历使用ID
2、
一般索引 KEY shopid
一般索引 KEY poiid
组合索引 KEY combined(shopid,poiid)
使用时只触发了索引merge i2 && KEY combined
建议:
删除Key shopid索引,减少索引占用空间
3、一个复杂SQL 还是多个简单SQL
1、查看表状况 show table status like ‘table_shop’
Rows : 180000000
Data_length : 30G
单表数据量过大,建议单表不超过1千万行
2、是否必须走主库
Master-Slave架构,主库单节点,容易成为资源瓶颈
3、范式:确保每列的原子性(不可分解)、唯一性
反范式:通过冗余字段,提高查询效率
换存储引擎、缓存
业务逻辑优化
联合索引
对(a,b,c)进行联合索引,判断是否走索引问题
a = 1 //true
a = 1 and b = 2 //true
b = 2 and a = 1 //true,Mysql有优化器会自动调整a,b的顺序与索引顺序一致,注意把区分度高的字段放在前面
b = 1 //false,
a = 1 and b = 2 and c > 3 and d = 4 //a,b,c三个字段能用到索引,而d就匹配不到,最左匹配原则遇到范围查询就停止匹配
如何建联合检索问题
SELECT * FROM table WHERE a = 1 and b = 2 and c = 3; // (a,b,c) (b,a,c) (c,a,b)都可以,将区分度高的字段放在前列
SELECT * FROM table WHERE a > 1 and b = 2; // (b,a)建立索引,优化器会帮我们调整where后a,b的顺序
SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3; // (b,a) 或(b,c)都可以的
SELECT * FROM `table` WHERE a = 1 ORDER BY b; // 对(a,b)建索引
SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1; //对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配
哪些情况不适合建索引
推荐学习:
https://ipu.sankuai.com/app/course/detail/1927
高性能SQL 和 MySQL官方文档(https://www.mysql.com)