mysql表复制 php
复制表结构+复制表数据前端
mysql> create table t3 like t1; mysql> insert into t3 select * from t1;
mysql索引 mysql
ALTER TABLE table_name ADD INDEX index_name (column_list) ALTER TABLE table_name ADD UNIQUE (column_list) ALTER TABLE table_name ADDPRIMARY KEY (column_list)
CREATE INDEX index_name ON table_name (column_list) CREATE UNIQUE INDEX index_name ON table_name (column_list)
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name ALTER TABLE table_name DROP PRIMARY KEY
mysql视图 sql
mysql> create view v_t1 as select * from t1 where id>4 and id<11; Query OK, 0 rows affected (0.00 sec)
mysql> ? view ALTER VIEW CREATE VIEW DROP VIEW
mysql> show tables;
mysql> drop view v_t1;
mysql内置函数 数据库
CONCAT (string2 [,… ]) //链接字串 LCASE (string2 ) //转换成小写 UCASE (string2 ) //转换成大写 LENGTH (string ) //string长度 LTRIM (string2 ) //去除前端空格 RTRIM (string2 ) //去除后端空格 REPEAT (string2 ,count ) //重复count次 REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符 SPACE(count) //生成count个空格
BIN (decimal_number ) //十进制转二进制 CEILING (number2 ) //向上取整 FLOOR (number2 ) //向下取整 MAX(num1 ,num2) //取最大值 MIN(num1,num2) //取最小值 SQRT(number2) //开平方 RAND() //返回0-1内的随机值
CURDATE() //返回当前日期 CURTIME() //返回当前时间 NOW() //返回当前的日期时间 UNIX_TIMESTAMP(date) //返回当前date的UNIX日间戳 FROM_UNIXTIME() //返回UNIX时间戳的日期值 WEEK(date) //返回日期date为一年中的第几周 YEAR(date) //返回日期date的年份 DATEDIFF(expr,expr2) //返回起始时间expr和结束时间expr2间天数
mysql预处理语句 后端
mysql> prepare stmt1 from 'select * from t1 where id>?';
mysql> set @i=1;
mysql> execute stmt1 using @i;
mysql> set @i=5;
mysql> execute stmt1 using @i;
mysql> drop prepare stmt1;
mysql事务处理 服务器
--关闭自动提交功能 mysql> set autocommit=0; --从表t1中删除了一条记录 mysql> delete from t1 where id=11; --此时作一个p1还原点: mysql> savepoint p1; --再次从表t1中删除一条记录: mysql> delete from t1 where id=10; --再次作一个p2还原点: mysql> savepoint p2; --此时恢复到p1还原点,固然后面的p2这些还原点自动会失效: mysql> rollback to p1; --退回到最原始的还原点: mysql> rollback ;
mysql存储 session
mysql> \d // mysql> create procedure p1() -> begin -> set @i=0; -> while @i<10 do -> select @i; -> set @i=@i+1; -> end while; -> end; -> //
mysql> \d ; mysql> call p1(); --查看procedure p1()的status信息 mysql> show procedure status\G --查看procedure p1()的具体信息: mysql> show create procedure p1\G
mysql触发器 socket
mysql> \d //
mysql> create trigger tg1 before insert on t1 for each ro >begin >insert into t2(id) values(new.id); >end// --准备两个空表t1和t2 mysql> select * from t1; mysql> select * from t2; --向t1表中插入多条数据: mysql> insert into t1 values(1),(2),(3),(4);
mysql>\d // mysql> create trigger tg2 beforedelete on t1 for each row >begin delete from t2 where id=old.id; >end// mysql>\d ;
mysql>\d // mysql> create trigger tg3 beforeupdate on t1 for each row >begin update t2 set id=new.id where id=old.id; >end// mysql>\d ;
mysql> show triggers;
重排auto_increment值 tcp
MYSQL数据库自动增加的ID如何恢复,清空表的时候。不能用
delete from tablename;
而是要用:
truncatetable tablename;
这样auto_increment 就恢复成1了
或者清空内容后直接用ALTER命令修改表:
altertable tablename auto_increment =1;
利用GROUP BY的WITH ROLLUP
mysql> select * from demo; +-------+-------+ | cname | pname | +-------+-------+ | bj | hd | | bj | xc | | bj | hd | | sh | dh | | sh | rg | | sh | dh | +-------+-------+ 9 rows in set (0.00 sec)
mysql> select cname,pname,count(pname) from demo group by cname,pname; +-------+-------+--------------+ | cname | pname | count(pname) | +-------+-------+--------------+ | bj | hd | 3 | | bj | xc | 2 | | sh | dh | 3 | | sh | rg | 1 | +-------+-------+--------------+ 4 rows in set (0.00 sec)
ysql> select cname,pname,count(pname) from demo group by cname,pname with rollup; +-------+-------+--------------+ | cname | pname | count(pname) | +-------+-------+--------------+ | bj | hd | 3 | | bj | xc | 2 | | bj | NULL | 5 | | sh | dh | 3 | | sh | rg | 1 | | sh | NULL | 4 | | NULL | NULL | 9 | +-------+-------+--------------+ 7 rows in set (0.00 sec)
使用外键须要注意的问题
mysql>create table temp( id int, name char(20), foreign key(id) references outTable(id) on delete cascade on update cascade);
注意:Innodb类型的表支持外键,myisam类型的表,虽然建立外键能够成功,可是不起做用,主要缘由是不支持外键。
优化SQL语句的通常步骤
mysql> show [session|global]status;
其中:session(默认)表示当前链接,global表示自数据库启动至今
mysql>show status; mysql>show global status; mysql>show status like ‘Com_%’; mysql>show global status like ‘Com_%’;
参数说明:
Com_XXX表示每一个XXX语句执行的次数如:
Com_select 执行select操做的次数,一次查询只累计加1
Com_update 执行update操做的次数
Com_insert 执行insert操做的次数,对批量插入只算一次。
Com_delete 执行delete操做的次数
只针对于InnoDB存储引擎的:
InnoDB_rows_read 执行select操做的次数
InnoDB_rows_updated 执行update操做的次数
InnoDB_rows_inserted 执行insert操做的次数
InnoDB_rows_deleted 执行delete操做的次数
其余:
connections 链接mysql的数量
Uptime 服务器已经工做的秒数
Slow_queries:慢查询的次数
explain select * from table where id=1000; desc select * from table where id=1000;
mysql> explain select count(*) from stu where name like "a%"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: stu type: range possible_keys: name,ind_stu_name key: name key_len: 50 ref: NULL rows: 8 Extra: Using where; Using index 1 row in set (0.00 sec)
每一列的简单解释
id: 1 select_type: SIMPLE 表示select的类型,常见的取值有SIMPLE()简单表,即不使用表链接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SESECT)等 table: stu 输出结果集的表 type: range 表示表的链接类型,性能有好到差:system(表仅一行)、const(只一行匹配)、eq_ref(对于前面的每一行使用主键和惟一)、ref(同eq_ref,但没有使用主键和惟一)、ref_or_null(同前面对null查询)、index_merge(索引合并优化)、unique_subquery(主键子查询)、index_subquery(非主键子查询)、range(表单中的范围查询)、index(都经过查询索引来获得数据)、all(经过全表扫描获得的数据) possible_keys: name,ind_stu_name 表查询时可能使用的索引。 key: name 表示实际使用的索引。 key_len: 50 索引字段的长度 ref: NULL rows: 8 扫描行的数量 Extra: Using where; Using index 执行状况的说明和描述
索引问题
MyISAM存储引擎的表的数据和索引是自动分开存储的,各自是独一的一个文件;InnoDB存储引擎的表的数据和索引是存储在同一个表空间里面,但能够有多个文件组成。MySQL目前不支持函数索引,可是能对列的前面某一部分进行索引,例如name字段,能够只取name的前4个字符进行索引,这个特性能够大大缩小索引文件的大小,用户在设计表结构的时候也能够对文本列根据此特性进行灵活设计。
mysql>create index ind_company2_name on company2(name(4)); --其中company表名ind_company2_name索引名
一、使用索引
(1)对于建立的多列索引,只要查询的条件中用到最左边的列,索引通常就会被使用。以下建立一个复合索引。
mysql>create index ind_sales2_com_mon on sales2(company_id,moneys);
而后按company_id进行查询,发现使用到了复合索引
mysql>explain select * from sales2 where company_id=2006\G
使用下面的查询就没有使用到复合索引。
mysql>explain select * from sales2 where moneys=1\G
(2) 使用like的查询,后面若是是常量而且只有%号不在第一个字符,索引才可能会被使用,以下:
mysql> explain select * from company2 where name like "%3"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
以下这个使用到了索引,而下面例子可以使用索引,区别就在于“%”的位置不一样,上面的例子是吧“%”放在了第一位,而下面的例子则没有
mysql> explain select * from company2 where name like "3%"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: range possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: NULL rows: 103 Extra: Using where 1 row in set (0.00 sec)
(3)若是对大的文本进行搜索,使用全文索引而不使用like“%...%”.
(4)若是列名是索引,使用column_name is null将使用索引。以下
mysql> explain select * from company2 where name is null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ref possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: const rows: 1 Extra: Using where 1 row in set (0.00 sec)
(1)若是MySQL估计使用索引比全表扫描更慢,则不使用索引。例如若是列key_part1均匀分布在1到100之间,查询时使用索引就不是很好
mysql>select * from table_name where key_part1>1 and key_part<90;
(2)若是使用MEMORY/HEAP表而且where条件中不使用“=”进行索引列,那么不会用到索引。Heap表只有在“=”的条件下会使用索引。
(3)用or分割开的条件,若是or前的条件中的列有索引,然后面的列中没有索引,那么涉及的索引都不会被用到。
mysql>show index from sales\G *************************** 1. row *************************** …… key_name: ind_sales_year seq_in_index:1 Column_name: year ……
从上面能够发现只有year列上面有索引。来看以下的执行计划。
mysql> explain select * from sales where year=2001 or country=‘China’\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales type: ALL possible_keys: ind_sales_year key: NULL key_len: NULL ref: NULL rows: 12 Extra: Using where 1 row in set (0.00 sec)
(4)若是不是索引列的第一部分,以下例子:可见虽然在money上面建有复合索引,可是因为money不是索引的第一列,那么在查询中这个索引也不会被MySQL采用。
mysql> explain select * from sales2 where moneys=1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
(5)若是like是以%开始,可见虽然在name上面建有索引,可是因为where 条件中like的值的“%”在第一位了,那么MySQL也会采用这个索引。
(6)若是列类型是字符串,但在查询时把一个数值型常量赋值给了一个字符型的列名name,那么虽然在name列上有索引,可是也没有用到。
mysql> explain select * from company2 where name name=294\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: ind_company2_name key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
而下面的sql语句就能够正确使用索引。
mysql> explain select * from company2 where name name=‘294’\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ref possible_keys: ind_company2_name key: ind_company2_name key_len: 23 ref: const rows: 1 Extra: Using where 1 row in set (0.00 sec)
若是索引正在工做,Handler_read_key的值将很高,这个值表明了一个行被索引值读的次数。
Handler_read_rnd_next的值高则意味着查询运行低效,而且应该创建索引补救。
mysql> show status like 'Handler_read%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | Handler_read_first | 0 | | Handler_read_key | 5 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 2055 | +-----------------------+-------+ 6 rows in set (0.00 sec)
两个简单实用的优化方法
mysql> CHECK TABLE tbl_name[,tbl_name] …[option] …option = { QUICK | FAST | MEDIUM| EXTENDED | CHANGED} mysql> check table sales; +--------------+-------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------+-------+----------+----------+ | sakila.sales | check | status | OK | +--------------+-------+----------+----------+ 1 row in set (0.01 sec)
优化表的语法格式:
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [,tbl_name]
若是已经删除了表的一大部分,或者若是已经对含有可变长度行的表进行了不少的改动,则须要作按期优化。这个命令能够将表中的空间碎片进行合并,可是此命令只对MyISAM、BDB和InnoDB表起做用。
mysql> optimize table sales; +--------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------+----------+----------+----------+ | sakila.sales | optimize | status | OK | +--------------+----------+----------+----------+ 1 row in set (0.05 sec)
经常使用SQL的优化
当用load命令导入数据的时候,适当设置能够提升导入的速度。
对于MyISAM存储引擎的表,能够经过如下方式快速的导入大量的数据。
ALTER TABLE tbl_name DISABLE KEYS loading the data ALTER TABLE tbl_name ENABLE KEYS
DISABLE KEYS 和ENABLE KEYS 用来打开或关闭MyISAM表非惟一索引的更新,能够提升速度,注意:对InnoDB表无效。
--没有使用打开或关闭MyISAM表非惟一索引: mysql> load data infile ‘/home/mysql/film_test.txt’into table film_test2; Query OK,529056 rows affected (1 min 55.12 sec) Records:529056 Deleted:0 Skipped:0 Warnings:0 --使用打开或关闭MyISAM表非惟一索引: mysql> alter table film_test2 disable keys; Query OK,0 rows affected (0.0 sec) mysql> load data infile ‘/home/mysql/film_test.txt’into table film_test2; Query OK,529056 rows affected (6.34 sec) Records:529056 Deleted:0 Skipped:0 Warnings:0 mysql> alter table film_test2 enable keys; Query OK,0 rows affected (12.25 sec) --以上对MyISAM表的数据导入,但对于InnoDB表并不能提升导入数据的效率
(1)针对于InnoDB类型表数据导入的优化
由于InnoDB表的按照主键顺序保存的,因此将导入的数据主键的顺序排列,能够有效地提升导入数据的效率。
--使用test3.txt文本是按表film_test4主键存储顺序保存的 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK, 1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --使用test3.txt没有任何顺序的文本(效率慢了1.12倍) mysql> load data infile ‘/home/mysql/film_test4.txt’into table film_test4; Query OK, 1587168 rows affected (31.16 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
(2)关闭惟一性效验能够提升导入效率
在导入数据前先执行set unique_checks=0,关闭惟一性效验,在导入结束后执行set unique_checks=1,恢复惟一性效验,能够提升导入效率。
--当unique_checks=1时 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --当unique_checks=0时 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (19.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
(3)关闭自动提交能够提升导入效率
在导入数据前先执行set autocommit=0,关闭自动提交事务,在导入结束后执行set autocommit=1,恢复自动提交,能够提升导入效率。
--当autocommit=1时 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --当autocommit=0时 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (20.87 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
尽可能使用多个值表的insert语句,这样能够大大缩短客户与数据库的链接、关闭等损耗。
可使用insert delayed(立刻执行)语句获得更高的效率。
将索引文件和数据文件分别存放不一样的磁盘上。
能够增长bulk_insert_buffer_size 变量值的方法来提升速度,可是只对MyISAM表使用当从一个文件中装载一个表时,使用LOAD DATA INFILE。这个一般比使用不少insert语句要快20倍。
若是查询包含group by但用户想要避免排序结果的损耗,则可使用使用order by null来禁止排序:
以下没有使用order by null来禁止排序
mysql> explain select id,sum(moneys) from sales2 group by id\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using temporary;Using filesort 1 row in set (0.00 sec)
以下使用order by null的效果:
mysql> explain select id,sum(moneys) from sales2 group by id order by null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using temporary 1 row in set (0.00 sec)
下面是采用嵌套查询的效果(可使用更有效的连接查询(Join)替代)。
mysql> explain select * from sales2 where company_id not in(select id from company2)\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
*************************** 2. row *************************** id: 2 select_type: SIMPLE table: company2 type: index_subquery possible_keys: ind_company2_id key: ind_company2_id key_len: 5 ref: func rows: 2 Extra: Using index 1 row in set (0.00 sec)
下面是使用更有效的连接查询(Join)
mysql> explain select * from sales2 left join company2 on sales2.company_id = company2.id where sales2.company_id is null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: ind_sales2_companyid_moneys key: ind_sales2_companyid_moneys key_len: 5 ref: count rows: 1 Extra: Using where 1 row in set (0.00 sec) *************************** 2. row *************************** id: 2 select_type: SIMPLE table: company2 type: index_subquery possible_keys: ind_company2_id key: ind_company2_id key_len: 5 ref: func rows: 1 Extra: 1 row in set (0.00 sec)
从执行计划中能够明显看出查询扫描的记录范围和使用索引的状况都有了很大的改善。链接(JOIN)子因此更有效率一些,是由于MySQL不须要再内存中建立临时表来完成这个逻辑上的须要两个步骤的查询工做。
数据库优化
在MySQL中,可使用函数PROCEDUREANALYSE()对当前应用的表进行分析,改函数能够对数据表中列的数据类型提出优化建议,用户能够根据应用的实际状况酌情考虑是否实施优化。
mysql> select * from duck_cust procedure analyse()\G *************************** 1. row *************************** Field_name: sakila.duch_cust.cust_num Min_value: 1 Max_value: 6 Min_length: 1 Max_length: 1 Empties_or_zeros: 0 Nulls: 0 Avg_value_or_avg_length: 3.5000 Std: 1.7078 Optimal_fieldtype: ENUM(‘1’,‘2’,‘3’,‘4’) NOT NULL *************************** 2. row *************************** ……
1.分库分表
2.分区
主要目的:
1.减小表的记录数
2.减少对操做系统的负担压力
中间表的产生:
1.view 视图
2.从新生成一个新表
Mysql服务器优化
1.
lock table t1 read
2.开启另外一个mysql链接终端,接着去尝试:
select * from t1
3.再insert、update和delete t1这张表,你会发现全部的数据都停留在终端上没有真正的去操做
4.读锁定对咱们在作备份大量数据时很是有用.
mysqldump -uroot -p123 test >test.sql
1.
lock table t1 write
2.打开另外一个mysql终端,尝试去select、insert、update和delete这张表t1,你会发现都不能操做,都会停留在终端上,只有等第一个终端操做完毕,第二个终端才能真正执行.
3.可见表的写锁定比读锁定更严格
4.通常状况下咱们不多去显式的去对表进行read 和write锁定的,myisam会自动进行锁定的.
Mysql服务器优化
1.log-bin=mysql-bin
查看bin-log日志:
mysql> show binary logs;
查看最后一个bin-log日志:
mysql> show master status;
开户和设置慢查询时间:
vi /etc/my.cnf
log_slow_queries=slow.log long_query_time=5
慢查询次数:
mysql> show global status like "%quer%"
mysql socket没法登陆
1. 有时登陆mysql时提示不能用socket登陆,此时能够换成tcp方式去登陆,可是能够测试时能够这样用,可是必需要在php去用以前把这个事情解决了.
[root@localhost mysql]# mysql -uroot -pwei --protocol tcp -hlocalhost Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 34 Server version: 5.0.77-log Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
这样就能够登陆,这样就不用mysql.sock来登陆,而mysql.sock是启动mysqld服务时产生的
root密码丢失破解 1.service mysqld stop 2. mysqld_safe --skip-grant-tables --user=mysql & //跳过受权表mysql.user和mysql.db这些表 3. mysql -uroot 4. set password=password("wei"); //用这一条语句结果报错,就是由于加了--skip-grant-tables 4. mysql>update user set password=password("wei") where user='root' and host='localhost'; 5. mysql> set password for root@localhost=password("wei"); 6. mysql> set password=password("wei"); //和第五步同样,均可能成功修改密码
我是天王盖地虎的分割线