您的位置:首页 > 数据库 > MySQL

mysql

2016-06-21 07:26 633 查看
摘要: mysql基础

1、使用group_concat(expr) 能将 将同一字段的多行内容以一定的函数合成一行内容

2、


3、left join where 和 on的区别,where是先关联再筛选,on是先筛选再关联,on只会影响B表中的数据行数

4、 truncate table course 清空操作,自增的id从1开始,将id重置

5、mysql 行转列





SELECT S.studentname,SUM(CASE SUBJECT WHEN '语文' THEN score ELSE 0 END) 语文,
SUM(CASE SUBJECT WHEN '数学' THEN score ELSE 0 END) 数学,
SUM(CASE SUBJECT WHEN '英语' THEN score ELSE 0 END) 英语 FROM student AS s GROUP BY S.studentname;

6、


Create Table
CREATE TABLE `zhubing_disease_symptom_tree` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`symptom_tree_id` bigint(20) DEFAULT NULL,
`disease_id` bigint(20) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`temperature_stage_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=154 DEFAULT CHARSET=utf8


Create Table
CREATE TABLE `zhubing_symptom_tree` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`symptom_id` bigint(20) DEFAULT NULL,
`parent_id` bigint(20) DEFAULT NULL,
`symptom_chain` text,
`path_level` int(11) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`tree_order` int(11) DEFAULT NULL,
`temperature_stage_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8
7、从MySQL4.1开始,varchar (N)中的N指的是该字段最多能存储多少个字符(characters),不是字节数。
不管是一个中英文字符或者数字、或者一个汉字,都当做一个字符。在4.1之前,N表示的是最大存储的字节数(bytes)。

length: 是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符

char_length:不管汉字还是数字或者是字母都算是一个字符

一、sql优化
1、通过show status like 'Com_%',可以了解各种sql的执行频率,数据库是的应用是以插入更新为主还是以查询操作为主的
2、定位执行效率较低的sql语句,通过慢查询的日志定位哪些执行效率较低的sql(超过多少秒的sql语句的日志文件),慢查询日志是在查询结果结束之后才记录的。可以使用show processlist命令查看当前mysql在进行的线程,是否死锁,实时查看线程的状态
3、explain分析低效率的sql执行计划,explain extended 可以迅速获取一个优化器改写的sql,更加易读,explain partitions 查看sql所访问的分区。show profile分析sql,
show profile for query语句能够看到执行过程中线程的每个状态和消耗的时间。我们知道myisam表有表元数据缓存,例如count(*),那么对一个myisam表的count(*)不需要消耗太多的资源,而对innodb,没有这种缓存,执行慢。
4、通过对sql的跟踪trace,通过trace文件了解为什么优化器选择a执行计划而不选择b执行计划,通过trace分析优化器如何选择执行计划,使用方式:SET OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=on;

SET OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;

SELECT ID FROM PERSON;

SELECT *FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE
以上步骤就可以确定问题的原因
5、mysql的索引类型:B-tree,Hash,R-tree,FUll-text
memory默认hash,也支持b-tree,myisam支持B-tree,R-tree,FUll-text,innodb支持b-tree
6、典型使用索引:最左匹配原则可以算是mysql中b-tree索引使用的首要原则
匹配最左前缀,仅仅使用索引中最左边的列进行查找,如c1,c2,c3的联合索引,不能被c2,(c2+c3)利用到的
如果列明是索引,那么列名is null就会使用索引
当查询的列都在索引字段的时候,查询的效率最高

典型不适用索引:
1)b-tree,以%开头的like没法使用索引。innodb都是聚簇表的特点,索引都会比表小,扫描索引要比扫描表更快

PRIMARY:查询中最外层的SELECT(如两表做UNION或者存在子查询的外层的表操作为PRIMARY,内层的操作为UNION)

DERIVED:被驱动的SELECT子查询(子查询位于FROM子句)

//不使用索引情况

explain select *from actor where last_name like '%%';

//使用索引情况

explain slect *from (select actor_id from actor where last_name like '%%')a,actor b where a.actor.id=b.actor.id

理想情况是根据二级索引查主键,再根据主键回查

2)数据类型出现隐士转换也不会出现索引,如name字段,值不加引号则不会使用索引
3)or条件,必须都有索引,才会使用索引
筛选率越高,越容易使用索引
7、查看索引使用情况
show status like 'Handler_read%';
Handler_read_key很高,代表一个行被索引引用的次数
Handler_read_rnd_next的值很高则以为这查询效率底下
9、定期分析表和检查表:analyze table payment
check table payment
optimize table paymeng 优化表
需要在不繁忙的时候执行难,执行期间会对表进行锁
10、load命令导入数据,myisam通过打开和关闭非唯一索引的更新

load data infile‘/home/mysql/file’ into table film_test2;
innodb按照主键顺序插入速度快(无须插入会比较慢),导入前关闭唯一性校验set unique_check=0,导入后打开
导入前关闭自动提交 set autocommit=0,导入后打开自动提交

多个值表的insert语句insert into test values(1,2),(2,3);

inset delayed 语句,让insert马上执行,其实数据都被放到内存的队列中,并没有真正的写入磁盘,这笔每条语句分别插入快的多说明: INSERT DELAYED INTO,是客户端提交数据给MySQL,MySQL返回OK状态给客户端。而这是并不是已经将数据插入表,而是存储在内存里面等待排队。当mysql有空余时,再插入。这样的好处是,提高插入的速度,客户端不需要等待太长时间。坏处是,不能返回自动递增的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失;load data infile比insert快的多;

将索引文件和数据文件放在不同磁盘上存放

Innodb提供有insert buffer以批量操作减少IO

当mysql大批量插入数据的时候就会变的非常慢, mysql提高insert into 插入速度的方法有三种:

第一种插入提速方法:

如果数据库中的数据已经很多(几百万条), 那么可以 加大mysql配置中的 bulk_insert_buffer_size,这个参数默认为8M

bulk_insert_buffer_size=100M

第二种mysql插入提速方法:

改写所有 insert into 语句为 insert delayed into

这个insert delayed不同之处在于:立即返回结果,后台进行处理插入。

第三个方法: 一次插入多条数据:

insert中插入多条数据,举例:

insert into table values('11','11'),('22','22'),('33','33')...;

11、列,索引,存贮程序,触发器在任何平台上都大小写不敏感,unix系统上对表别名或者数据库名字大小写敏感,修改lower_case_tables_name可更改表名和数据库名称的大小写

12、使用外键应该注意的问题,当使用references table_name(col_name)子句定义时可以使用外部关键字,但没有实际的效果,只作为备忘录或者注释来提醒用户目前正定义的列只想另一个表中一个列,show create table 在innodb会显示外键的语句,但在myisam中不会

create table(primary key (id),constraint 'fk_userId_id' foreign key ('userid') references 'users2' ('id'));

13、order by rand() 随机抽取样本,即随机排序后,取前n条记录

14、group by with rollup不能和order by一起使用,互斥.

可以与union all相互转换

GROUPING
是一个聚合函数,它产生一个附加的列,当用 CUBE 或 ROLLUP 运算符添加行时,附加的列输出值为1,当所添加的行不是由 CUBE 或 ROLLUP 产生时,附加列值为0。
仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相联系的选择列表中才允许分组。

语法GROUPING ( column_name )
参数column_name
是 GROUP BY 子句中用于检查 CUBE 或 ROLLUP 空值的列。
返回类型int

Name        procedure        model           quantity
A               1                      φ50              500
A               1                      φ50              600
A               1                      φ100            500
A               2                      φ50              700
A               2                      φ100            200
B               1                      φ50              1000
使用了group by Name,procedure,model,quantity  with rollup
变成了:
Name        procedure        model           quantity
A               1                      φ50              1100
A               1                      φ100            500
A               1                      NULL           1600
A               2                      φ50              700
A               2                      φ100            200
A               2                      NULL            900
A               NULL                NULL           2500
B               1                      φ50              1000
B               1                      NULL            1000
B               NULL               NULL             1000
NULL         NULL               NULL             3500
我想把它显示成:
Name        procedure        model           quantity
A               1                      φ50              1100
A               1                      φ100            500
A的1小计                                               1600
A               2                      φ50              700
A               2                      φ100            200
A 的2小计                                              900
A 合计                                                   2500
B               1                      φ50             1000
B的1小计                                              1000
B合计                                                   1000
总计                                                      3500

CREATE TABLE #test (
Name   VARCHAR(10),
[procedure] CHAR(1),
model   VARCHAR(5),
quantity  INT
);

INSERT INTO #test
SELECT  'A', '1', 'φ50',  500  UNION ALL
SELECT  'A', '1', 'φ50',  600  UNION ALL
SELECT  'A', '1', 'φ100', 500  UNION ALL
SELECT  'A', '2', 'φ50',  700  UNION ALL
SELECT  'A', '2', 'φ100', 200  UNION ALL
SELECT  'B', '1', 'φ50',  1000;

SELECT
CASE
WHEN GROUPING(Name) = 1 THEN  '总计'
WHEN GROUPING(Name) = 0 AND GROUPING([procedure]) = 1 THEN  Name + '合计'
WHEN GROUPING(Name) = 0 AND GROUPING([procedure]) = 0 AND GROUPING([model]) = 1 THEN  Name + '的' + [procedure] +  '小计'
ELSE  Name
END  AS  Name,
CASE
WHEN GROUPING([model]) = 1 THEN ''
ELSE [procedure]
END  AS  [procedure],
ISNULL(model, '') AS model,
SUM(quantity) AS quantity
FROM
#test
group by
Name,
[procedure],
model with rollup;

Name              procedure model quantity
----------------- --------- ----- -----------
A                 1         φ100          500
A                 1         φ50          1100
A的1小计                                    1600
A                 2         φ100          200
A                 2         φ50           700
A的2小计                                     900
A合计                                      2500
B                 1         φ50          1000
B的1小计                                    1000
B合计                                      1000
总计                                       3500

(11 行受影响)

SQL  Server 2008 Express  下测试通过.
http://www.2cto.com/database/201304/206327.html http://wenku.baidu.com/link?url=VmW7X99967sq7DijLJWS4-tSzavFIB_Ik8QUcyvHblkRQveODbk77T4HAMDODudoLqqsnP6rJDhTI1IFmNaY11z7E9SH25Vfc4-j5WtzyFi
你会发现,cube与rollup用法不同,cube会对所有例进行分组汇总合计。
通过以上例子,可知:
如果是Group by ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。
如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。 grouping_id()可以美化效果。除了使用GROUPING函数,还可以使用GROUPING_ID来标识GROUP BY的结果。

15、共同使用group by语句和bit_and 、bit_or 函数完成统计工作

1)记录每个用户每次来超市都购买了哪些的商品。一般思路,主表记录用户,购买时间。另一张表记录购买的商品的详细信息。但这样的结构设计比较复杂,可以用一个字段表示记录各个商品是否购买

2)存储一个十进制,把他转换 成二进制,每一位都代表一个商品,1代表购买过,0代表没购买过。bit_and就是将两次购买的进行与运算,判断出两次都购买的商品,bit_or就是将两次购买进行or运算,判断出两次购买都买了哪些商品

16、mysql排序有2种,一种通过有序索引顺序扫描直接返回有序数据,第二种对返回数据进行排序,常说的filesort,尽量减少额外的排序,直接通过索引返回有序数据

17、group by会进行filesort,可以显示的order by null 不进行filesort

18、表连接比子查询更有效率,mysql不需要在内存中创建临时表

表关联是可以利用两个表的索引的,如果是用子查询,至少第二次查询是没有办法使用索引的

select *from customer where customer_id not in(select customer_id from paument)

select * from customer a left join payment b on a.customer_id=b.custimer_id where b.customer_id is null

19、or两侧都为独立的索引才能被用到,复合的索引不可以

20、sql提示, use index ,ignore index,force index

21、优化表的数据类型

select * from duck_cust procedure analyse();

22、逆规范化

增加冗余列(多个表具有相同的列),派生列(增加的列是其他的表计算生成的),重新组表,分割表

逆规范化技术需要维护数据的完整性,通过批处理,这种情况对实时性要求不高

数据的完整性也可由应用逻辑来实现,这就是要求必须在同一事物中队所有涉及的表进行增删改查的操作。

触发器是实时的,是解决这类问题的最好的办法

23、拆表,垂直拆分和水平拆分

24、myisam和memory是表级锁,BDB采用的是页面锁,但也支持表级锁。innodb支持行级锁,也支持表级锁

表级锁:读写串行,开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率高,并发度最低

表级锁的锁模式,读锁和写锁,对myisam表的读操作,不会阻塞其他用户对同一表的读操作,但会阻塞对通过一个表的写请求。对myisam表的写操作,则会阻塞其他用户对同一表的读和写操作。myisam总是一次获得sql语句锁需要的全部锁,这也是myisam表不会出现死锁的原因。

显示锁定表用lock tables read 不仅需要一次锁定用到的所有表,而且同一个表在sql语句中出现多少次,就要通过与sql语句中相同的别名锁定多少次,否则也会出错。

特定情况下支持并发读写,需设置变量concurrent_inert,当表的中间没有被删除的行,允许在一个进程读表的同时,另一个进程从表尾插入记录

锁的调度机制:mysql认为写请求一般比读请求重要,这就是不适合有大量更新和查询的原因,容易造成查询很难获得读锁,从而可能永远阻塞,可以更新优先级,或者查询优先的方法解决问题。

行级锁:innodb和myisam最大的不同是,支持事务和行级锁

事务的属性:原子性,一致性,隔离性,持久性

并发处理带来的问题:更新丢失(两个人修改同一个文件,后者覆盖的问题。不单要靠数据库,还要对更新的数据增加必要的锁),脏读,不可重复读,幻读

数据库实现事务隔离的方式:加锁或者在请求的时间点生成一个快照,通过这个快照进行一致性的读取。数据库可以提供同一个数据的多个版本,叫多版本数据库MCC或者MVCC

行锁:共享锁和排它锁

表锁:意向共享锁和意向排它锁

多粒锁机制

innodb的行锁匙通过给索引上的索引项来加锁实现的,如果没有索引,innodb将通过隐藏的聚簇索引来对记录加锁

为什么要分表和分区?

日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。

什么是分表?

分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它。

什么是分区?

分区和分表相似,都是按照规则分解表。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据。

mysql分表和分区有什么联系呢?
1.都能提高mysql的性高,在高并发状态下都有一个良好的表现。
2.分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等。
3.分表技术是比较麻烦的,需要手动去创建子表,app服务端读写时候需要计算子表名。采用merge好一些,但也要创建子表和配置子表间的union关系。
4.表分区相对于分表,操作方便,不需要创建子表。

分表的几种方式:

1、mysql集群

它并不是分表,但起到了和分表相同的作用。集群可分担数据库的操作次数,将任务分担到多台数据库上。集群可以读写分离,减少读写压力。从而提升数据库性能。

MySQL Proxy最强大的一项功能是实现“读写分离(Read/Write Splitting)”。基本的原理是让主数据库处理事务性查询,而从数据库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库。 当然,主服务器也可以提供查询服务。使用读写分离最大的作用无非是环境服务器压力。

1、前提是主键自增,获取插入后记录的主键:insert语句执行完后执行 SELECT LAST_INSERT_ID();返回插入的主键值

1、mysql 表锁,读和写是总体上是串行的,也支持并发插入concurrent_insert(需要配置系统变量,可以解决对同一个表查询和插入的锁竞争)。当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作,其他线程的读写都会等待,直到锁被释放。myisam在执行查询语句select前会自动给设计的所有的表加读锁。例如:查询订单表和订单明细表的总金额时,如果查询之前不给这两个表加锁,很可能查询的总金额不一致。myisam总是一次获取到sql语句中所需要的全部锁。mysiam以写进程为主,会造成查询操作很能获取到读锁。可以通过修改myisam的调度行为,如:以读请求为优先,将更新请求的优先级降低,降低优先级来解决读锁等待严重的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: