2019独角兽企业重金招聘Python工程师标准>>>
修改字符集
查看字符集
show variables like 'character%' show variables like '%char%'
上面的两个命令都可以,我一般使用的下面的,会出来如下几个字符集设定的选项:
character_set_client:客户端请求数据的字符集character_set_connection:从客户端接收到数据,然后传输的字符集character_set_database:默认数据库的字符集,无论默认数据库如何改变,都是这个字符集;如果没有默认数据库,那就使用 character_set_server指定的字符集,
这个变量建议由系统自己管理,不要人为定义。character_set_filesystem:把os上文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的character_set_results:结果集的字符集character_set_server:数据库服务器的默认字符集character_set_system:这个值总是utf8,不需要设置,是为存储系统元数据的字符集
修改配置文件
修改/etc/my.cnf配置文件
在client下做如下一个选项的修改
[client] default-character-set=utf8 [mysqld] character_set_server=utf8 character_set_client=utf8 collation-server=utf8_general_ci lower_case_table_names=1 max_connections=1000 [mysql] default-character-set=utf8
配置文件
目前整个配置文件内容
[client] default-character-set=utf8 [mysqld] server-id=1 log-bin=mysql-bin datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 character_set_server=utf8 character_set_client=utf8 collation-server=utf8_general_ci [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid [mysql] default-character-set=utf8
log-bin
定义主从复制文件前缀,后面生成的文件在datadir+logbin-filename
如:
里面不仅有log-bin文件,还有创建的数据库对应的目录等
log-error
MySql的一些重要的数据信息都会在里面,日常运维监控都需要打开看看,例如将执行时间超过1秒的SQL输出
datadir
-
frm文件-相当于表的元数据
-
myd文件-表的数据文件
-
myi文件-表的索引文件
SQL性能下降原因
可能问题
1.查询语句写的烂
SQL关联的表很多,条件很复杂,很多子查询等,导致生成的执行计划有问题而无法生成索引
2.索引失效
单值索引:索引建立在单列上
组合索引:索引建立在多个字段上,如果查询的条件经常出现多列的同一个组合,那么创建组合索引非常高效
3.关联查询太多
现在硬件设备都已经起来的,数据库表设计几乎都不在严格遵循三范式,增加冗余,提高查询速度,以空间换时间。不过这样设计也有一些毛病,在做update的时候就必须修改更多的地方,否则会导致数据一致性问题
在分布式数据库中,如果跨主机关联太多,会导致大量的网络通信,极大的增加了SQL执行时长
如果确实不得不关联很多表,建议将一个大SQL拆分成小SQL,增强SQL执行计划的稳定性
4.服务器调优
修改排序缓冲和数据缓冲大小,修改线程数大小
关联查询
SQL读取执行顺序
SELECT distinct column_list FROM taba JOIN tabb ON join_condition WHERE where-condition GROUP BY group-by-list HAVING having-condition ORDER BY order-by-condition LIMIT limit-number
Mysql读取顺序
先求关联表的笛卡尔积——》得到主表结果数据——》做join,不符合on的数据也补充到结果中——》做条件过滤——》分组——》分组过滤——》结果集列筛选——》排序——》限定返回结果集
7中JOIN写法
1.INNER JOIN 内连接
SELECT <select_list>
FROM taba a
INNER JOIN tabb b
ON a.key = b.key
2.LEFT JOIN 左外连接
SELECT <select_list>
FROM taba a
LEFT JOIN tabb b
ON a.key = b.key
3.RIGHT JOIN 右外连接
SELECT <select_list>
FROM taba a
RIGHT JOIN tabb b
ON a.key = b.key
4.LEFT JOIN 求差
SELECT <select_list>
FROM taba a
LEFT JOIN tabb b
ON a.key = b.key
WHERE b.key is NULL
5.RIGHT JOIN 求差
SELECT <select_list>
FROM taba a
RIGHT JOIN tabb b
ON a.key = b.key
WHERE a.key is NULL
6.FULL JOIN 求并集
SELECT <select_list>
FROM taba a
FULL OUTER JOIN tabb b
ON a.key = b.key
7.FULL JOIN 求非交叉结果集
SELECT <select_list>
FROM taba a
FULL OUTER JOIN tabb b
ON a.key = b.key
WEHRE a.key is NULL OR b.key is NULL
索引
什么是索引
为了提高数据查询速度而设计的数据结构,一般情况下这种数据结构都是B+树(一颗已经排好序的树)。查询时,从树的根节点开始比较,小于根的走左孩子,大于根的走右孩子。
优势
查询时走索引比全表扫描可以大大降低IO,提高查询速度
索引是已经做完排序的列,拿到的数据是已经有序,减少CPU的时候
如果返回的列是索引列,那么都不需要从数据块从拿数据。
劣势
增加了额外的存储需求
如果表设计有问题,而且查询条件很多,建很多索引的话,表所对应的索引甚至可能比表占用的空间还大
索引的存在会降低DML效率,频繁的DML操作甚至会影响执行计划,错误的执行计划会导致SQL执行很慢
如果表很大,索引经常可能需要不停的优化,采集表的统计信息,基于更好更全的统计信息才能有更优的执行计划生成
列有大量NULL值不建议创建索引
索引的分类
1.单值索引:根据一个列创建索引,然而大多数情况下都是根据查询条件创建多值索引
2.唯一索引:索引列的数据是唯一的
3.复合索引:索引的列有多个,比如根据入学时间和学号区间查询所有学生,那么就可以创建一个符合索引(入学时间+学号)
索引B+树
假设要查询key=29,根磁盘块1中的17和35比,下一步应该找磁盘快3中的P2,在与该P2中的26和30比,下一步找磁盘快8,找到29这个索引项,然后拿该索引项的指针去数据区拿真实的数据行
该如何决定是否创建索引
1.主键会自动创建索引
2.频繁查询的条件需要建立复合索引
3.和其他表有外键的列,要创建索引
4.频繁执行DML操作的字段不适合创建索引,原因是DML会导致索引重建
5.where 条件用不到的列不适合创建索引
6.抛开主键和特殊场景,一般都是创建复合索引
7.在设计组合索引的时候,应该考虑到查询字段需求和排序字段需求,尽量保持复合索引字段与查询排序条件一致,可以提高效率
8.查询中统计或者分组的字段
9.表太小完全没有必要创建索引,因为只需要一次IO就把整表拿了过来
10.重复值严重的列不适合创建索引,比如100W条记录,而某一列只有3种重复的值,而且三种值绝大多数都是某一种,那么根据该列查询时,选择率非常低,近似于全表扫描。在生产中,主要是表的状态字段或者性别字段等等
有这么多限制,可能创建出来的索引可能会很多,特别是字段特别多的表,这种情况最好和DBA一起协商