mysql进阶
1.数据类型
mysql的数据类型众多,但是从大的分类上,可以分为下面几种类型
- 整数,tinyint、smallint、mediumint、int、bigint
- 定点数,decimal(m,n)
- 浮点数,float(m,d)、real(m,d)、DOUBLE PRECISION(M,D)
- bit
- 字符串:CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET
- 日期,date、time、datetime、timestamp、year
在使用字段类型时,我们一般的原则都是用最小满足原则,比如能用tinyint就不用int
2.mysql存储引擎
show storage engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
在这么多的存引擎中,我们常用的有两种,一种是InnoDB,另外一种是MyISAM;其中InnoDB支持事务,大多数情况下我们都使用该引擎;如果数据仅仅是查询,变更的很少,不需要事务的支持,那么可以采用MyISAM,查询性能会更高
3.mysql执行计划
执行计划,简单的来说,是SQL在数据库中执行时的表现情况,通常用于SQL性能分析,优化等场景
我们直接看一个sql的执行计划
mysql> explain select a.* from member a
-> inner join memberinfo b on a.mid = b.mid
-> where
-> a.mid in (select mid from product where pid>10000);
+----+--------------------+---------+----------------+---------------------------+-------------------+---------+-------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+----------------+---------------------------+-------------------+---------+-------------------+--------+--------------------------+
| 1 | PRIMARY | b | index | PRIMARY,PK_memberinfo_mid | PK_memberinfo_mid | 4 | NULL | 186174 | Using where; Using index |
| 1 | PRIMARY | a | eq_ref | PRIMARY | PRIMARY | 4 | ucunion_ovs.b.mid | 1 | |
| 2 | DEPENDENT SUBQUERY | product | index_subquery | PRIMARY,key_mid | key_mid | 4 | func | 105562 | Using index; Using where |
+----+--------------------+---------+----------------+---------------------------+-------------------+---------+-------------------+--------+--------------------------+
在上面的表格中,怎么解读呢
- id:表示查询中select操作表的顺序,按顺序从大到小依次执行,比如上面的sql中,in的子查询会先执行
- select_type:表示选择类型,常见可选择有:SIMPLE(简单的), PRIMARY(最外层) ,SUBQUERY(子查询)
- type:表示访问类型,常见有:ALL(全表扫描),index(所以扫描),range(范围扫描),ref(非唯一索引扫描)
- table,数据所在的表
- possible_keys,可能使用的索引
- key:实际使用的索引
- key_len:索引列所用的字节数
- ref:连接匹配条件,如果走主键索引的话,该值为: const, 全表扫描的话,为null值
- row,扫描的行数,行数越少,查询效率就会越高,我们的优化大部分都是为了降低该值
- extra:这个属性非常重要,该属性中包括执行SQL时的真实情况信息,常用的有"Using temporary",使用临时表;"using filesort": 使用文件排序
4.mysql的索引
关于mysql索引的细节非常多,不打算展开,可以参考下面的内容
mysql索引
5.mysql类型转换
在java中,我们都知道int与Integer的自动转化关系,同理在mysql中也有相应的类型转换,程序总是相通的...
比如mysql中,int与varchar会隐形转换
除了使用mysql的隐形转换,还可以CAST函数进行显示的类型转换,支持的数据类型如下
+----------------------+
| Database |
+----------------------+
| date |
| datetime |
| time |
| decimal |
| char |
| nchar |
| signed |
| unsigned |
| binary |
| json |
+----------------------+
mysql> select cast('2018-12-12' as date);
+----------------------------+
| cast('2018-12-12' as date) |
+----------------------------+
| 2018-12-12 |
+----------------------------+
6.mysql常见的坑
- 创建表时,数据类型错误,比如id使用了uuid
- 主外键字段类型不一致,导致join的性能低
- 没有给字段、表添加合适的注释
- 创建表时没有添加索引,项目初始时,由于数据小,感觉不到性能问题,但是当项目运行一段时间后,数据规模如果增长过快,但是没能及时添加索引,后续查询性能问题严重,但是添加索引的成本非常高,比如在2000W的表中,要做表的变更会非常麻烦
- 索引加错列,使用下面的命令,可以快速统计某个列的数据离散程度
mysql> select count(distinct(mid))/count(1) from member;
+-------------------------------+
| count(distinct(mid))/count(1) |
+-------------------------------+
| 1.0000 |
+-------------------------------+
1 row in set (0.51 sec)
mysql> select count(distinct(mgid))/count(1) from member;
+--------------------------------+
| count(distinct(mgid))/count(1) |
+--------------------------------+
| 0.0001 |
+--------------------------------+
在这两个列中,我们发现mid的离散程度是100%,也就是该列适合做为索引,而mgid列的离散程度却非常低,不适合作为索引
- 不该加索引的列添加了索引,索引是很需要占用存储空间的,并且索引越多,插入和update、delete的性能也会受到影响
7.10个使用的mysql命令
- show databases
+----------------------+
| Database |
+----------------------+
| information_schema |
| 100.84.72.153 |
| autotest |
| data_generate |
| dps_infobright |
+----------------------+
- use database_name
- show tables
+---------------------------------------------------+
| Tables_in_dps_stat |
+---------------------------------------------------+
| dps_report_publisher_pubid_pid_country_subpub_day |
| dps_scheduler_x_dataset |
| dps_scheduler_x_dataset_instance |
| dps_scheduler_x_job |
| dps_scheduler_x_job_instance |
+---------------------------------------------------+
- show full columns from table_name
+---------------------------------------------------------+
| Tables_in_ucunion_ovs |
+---------------------------------------------------------+
| 0601_memberinfo |
| 0601_product |
| 0601_publisher |
| 0601_publisher_info |
| 1_bak_config_keyvalue |
| INS_DATA_STATUS |
| STAT_UCWEB_GJ_USR_INC_HIVE_NEW_FR_VER_COU_CH |
+---------------------------------------------------------+
- select version()
- select current_user()
- show table status like "table_name"
+--------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------+
| member | InnoDB | 10 | Compact | 192938 | 198 | 38338560 | 0 | 17891328 | 7340032 | 197256 | 2018-07-16 10:29:50 | NULL | NULL | utf8_general_ci | NULL | | 用户表 |
+--------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------+
- show processlist
- show index from table_name
+--------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| member | 0 | PRIMARY | 1 | mid | A | 192646 | NULL | NULL | | BTREE | | |
| member | 0 | PK_member_account | 1 | account | A | 192646 | NULL | NULL | | BTREE | | |
| member | 1 | PK_member_mgid | 1 | mgid | A | 6 | NULL | NULL | | BTREE | | |
| member | 1 | index_amid | 1 | amid | A | 6 | NULL | NULL | | BTREE | | |
| member | 1 | index_amgid | 1 | amgid | A | 6 | NULL | NULL | | BTREE | | |
+--------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
查看表的索引,其中有个很重要的概念,叫做:Cardinality
这个值越大,那么该列的索引效果越好;比如在上面的索引中,amid,mgid,amgid都是不适合作为索引列
Cardinality
- explain select * from lh_user where created_at>"2017-12-09"
+----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | a | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | b | const | PRIMARY,PK_memberinfo_mid | PRIMARY | 4 | const | 1 | Using index |
+----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------------+