1.索引原理
磁盘预读:4096字节
b树:balance tree
b+树:数据只存储在叶子节点;在子节点之间加入了双向地址链接,更方便地在子节点之间进行数据的读取
索引原理
innodb:
汇集索引:对主键建立索引,并将该行全部数据存到树形结构里
辅助索引:除了主键以外全部的索引都是辅助索引
回表:只查询一个索引并不能解决查询中的问题,还须要到具体的表 中去获取整行数据
myisam:只有辅助索引
索引种类:
primary key 非空 + 惟一 + 汇集索引
unique 惟一 + 辅助索引
index 普通索引(辅助索引)
建立索引:create index index_name on 表(字段); # 建立索引后查询效率大幅提升,文件所占硬盘资源大幅提升
删除索引:drop index index_name on 表;
索引优缺点:
优:查找速度快
缺:浪费空间,拖慢写的速度 #不要在程序中建立无用的索引
2.正确使用索引
1.所查询的列不是建立了索引的列
2.在条件中不能带运算或者函数,必须是“字段 = 值”
3.若是建立索引的列的内容重复率高也不能有效利用索引 # 重复率不超过10%的列比较适合作索引
4.数据对应的范围若是太大的话,也不能有效利用索引 # between and > < >= <= != not in
5.like若是把%放在最前面也不能命中索引
6.多条件状况
and:只要一个条件列是索引列就能够命中索引
or:只有全部条件列都是索引才能命中索引
7.联合索引:在多个条件相连的状况下,使用联合索引的效率要高于使用单字段的索引
create index index_mix on 表(字段a,字段b);
1.建立索引的顺序a,b条件中从哪个字段开始出现了范围,索引就失效
2.联合索引在使用的时候遵循最左前缀原则
3.联合索引中只有使用and能生效,使用or失效
3.mysql收尾
explain:查看sql语句的执行计划
explain select * from 表 where 条件; # 查看是否命中了索引,命中的索引的类型
覆盖索引: explain出来的是using index;不用回表
索引合并: explain出来的是 using union;建立索引的时候分开建立的,用的时候(or的多条件状况下)合一块儿了
mysql开启慢日志:经过配置文件开启,筛选出程序中耗时长的sql语句
七表查询速度慢怎么办?
1.表结构:尽可能用固定长度的数据类型代替可变长数据类型;把固定长度的字段放在前面
2.数据的角度:若是表中的数据越多,查询效率越慢
列多:垂直分表 行多:水平分表
3.sql的角度:
尽可能把条件写细致,where条件多作筛选
多表状况下尽可能连表代替子查询
建立有效的索引,规避无效索引
4.配置角度:开启慢日志,确认有问题的sql语句
5.数据库:读写分离(解决数据库读的瓶颈)
数据库的导入导出
备份表:
mysqldump -uroot -p123 数据库 > 地址 # 整个库的表和数据
mysqldump -uroot -p123 库名 表名 表名 > 地址 # 单表(多表)的数据
备份库:
mysqldump -uroot -p123 --databases 库名 库名 > 地址 # 多库
恢复数据:
进入mysql切换到要恢复数据的库下面
sourse 以前备份的地址
开启事务,给数据加锁(行级锁)
begin;
select 字段 from 表 where 条件 for update;
update 表名 set 字段 = 值 where 条件;
commit;
4.sql注入
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password="123",database='day42')
cur = conn.cursor()
user = "kunkun' or 1=1 ;-- " # 因'--'注释的特性,致使此种写法造成sql注入
password = '*******'
sql = "select * from userinfo where username = %s and password =%s;"
cur.execute(sql,(user,password))
ret = cur.fetchone()
print(ret)
cur.close()
conn.close()