该数据库有三个在线重作日志组。经过LOGFILE子句来指定,MAXLOGFILES, MAXLOGMEMBERS, and MAXLOGHISTORY都是对日志文件的限制。php
MAXDATAFILES指定了数据库可以打开的数据文件的最大数量,该数量会影响到控制文件的大小。在建立数据库的过程当中所设定的參数,有些会受到其它因素的影响。前端
比方,设定了MAXDATAFILES以后,Oracle在控制文件里要分配空间存放数据文件的文件名称。即便数据库仅仅有一个数据文件。然而,因为控制文件自己也有大小的限制(跟操做系统有关)。很是有可能不能把所有CREATE DATABASE的參数都设置为他们理论上的最大值。mysql
初始化文件里的LOG_ARCHIVE_DEST_1,LOG_ARCHIVE_FORMAT, and LOG_ARCHIVE_START三个參数与归档有关。sql
mysql表复制 数据库
复制表结构+复制表数据后端
1
2
|
mysql>
create
table
t3
like
t1;
mysql>
insert
into
t3
select
*
from
t1;
|
mysql索引 bash
1
2
3
4
5
6
7
8
9
10
11
12
|
ALTER
TABLE
用来建立普通索引、
UNIQUE
索引或
PRIMARY
KEY
索引
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
CREATE
INDEX
index_name
ON
table_name (column_list)
CREATE
UNIQUE
INDEX
index_name
ON
table_name (column_list)
drop
index
DROP
INDEX
index_name
ON
talbe_name
alter
table
table
drop
ALTER
TABLE
table_name
DROP
INDEX
index_name
ALTER
TABLE
table_name
DROP
PRIMARY
KEY
|
mysql视图 session
建立视图
oracle
1
2
|
mysql>
create
view
v_t1
as
select
*
from
t1
where
id>4
and
id<11;
Query OK, 0
rows
affected (0.00 sec)
|
view视图的帮助信息
socket
1
2
3
4
|
mysql> ?
view
ALTER
VIEW
CREATE
VIEW
DROP
VIEW
|
查看视图
1
|
mysql> show tables;
|
删除视图v_t1
1
|
mysql>
drop
view
v_t1;
|
mysql内置函数
字符串函数
1
2
3
4
5
6
7
8
9
10
|
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
个空格
|
数学函数
1
2
3
4
5
6
7
|
BIN (decimal_number ) //十进制转二进制
CEILING (number2 ) //向上取整
FLOOR (number2 ) //向下取整
MAX
(num1 ,num2) //取最大值
MIN
(num1,num2) //取最小值
SQRT(number2) //开平方
RAND() //返回0-1内的随机值
|
日期函数
1
2
3
4
5
6
7
8
|
CURDATE() //返回当前日期
CURTIME() //返回当前时间
NOW() //返回当前的日期时间
UNIX_TIMESTAMP(
date
) //返回当前
date
的UNIX日间戳
FROM_UNIXTIME() //返回UNIX时间戳的日期值
WEEK(
date
) //返回日期
date
为一年中的第几周
YEAR
(
date
) //返回日期
date
的年份
DATEDIFF(expr,expr2) //返回起始时间expr和结束时间expr2间天数
|
mysql预处理语句
设置stmt1预处理,传递一个数据做为一个where推断条件
1
|
mysql>
prepare
stmt1
from
'select * from t1 where id>?
|
设置一个变量
mysql> set @i=1;
运行stmt1预处理
mysql> execute stmt1 using @i;
设置@i为5
mysql> set @i=5;
再次去运行stmt1
mysql> execute stmt1 using @i;
怎样删除预处理stmt1
mysql> drop prepare stmt1;
mysql事务处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
--关闭本身主动提交功能
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存储
建立一个存储p1()
1
2
3
4
5
6
7
8
9
10
|
mysql> \d
//
mysql> create procedure p1()
-> begin
->
set
@i=0;
->
while
@i<10
do
->
select
@i;
->
set
@i=@i+1;
-> end
while
;
-> end;
->
//
|
运行存储p1()
1
2
3
4
5
6
|
mysql> \d ;
mysql> call p1();
--查看procedure p1()的status信息
mysql> show procedure status\G
--查看procedure p1()的详细信息:
mysql> show create procedure p1\G
|
mysql触发器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
改动delimiter为
//
mysql> \d
//
建立一个名字为tg1的触发器,当向t1表中插入数据时。就向t2表中插入一条数据
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);
怎样制做删除表t1后t2表中的记录也会跟着删除呢
mysql>\d
//
mysql> create trigger tg2 beforedelete on t1
for
each row
>begin delete from t2 where
id
=old.
id
;
>end
//
mysql>\d ;
怎样制做更改表t1后t2表中的记录跟着个性呢
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值
1
2
3
4
5
6
7
8
9
10
11
|
MYSQL数据库本身主动增加的ID怎样恢复,清空表的时候。
delete from tablename;
而是要用:
truncatetable tablename;
这样auto_increment 就恢复成1了
或者清空内容后直接用ALTER命令改动表:
altertable tablename auto_increment =1;
|
利用GROUP BY的WITH ROLLUP
1
2
3
4
5
6
7
8
9
10
11
12
|
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)
|
对demo表依照cname、pname列分组对pname列进行聚合计算例如如下
1
2
3
4
5
6
7
8
9
10
11
|
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)
|
相同使用with rollupkeyword后,统计出不少其它的信息。例如如下。
注意:with rollup不可以和ordery by同一时候使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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)
|
使用外键需要注意的问题
建立外键的方式
1
2
|
mysql>create table temp(
id
int, name char(20), foreign key(
id
)
references outTable(
id
) on delete cascade on update cascade)。
|
注意:Innodb类型的表支持外键,myisam类型的表。尽管建立外键可以成功,但是不起做用,主要缘由是不支持外键。
优化SQL语句的通常步骤
经过show status命令了解各类SQL的运行频率
1
|
mysql> show [session|global]status;
|
当中:session(默认)表示当前链接,global表示自数据库启动至今
1
2
3
4
|
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 server已经工做的秒数
Slow_queries:慢查询的次数
定位运行效率较低的SQL语句
1
2
|
explain
select
*
from
table
where
id=1000;
desc
select
*
from
table
where
id=1000;
|
经过EXPLAIN分析较低效SQL的运行计划
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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个字符进行索引。这个特性可以大大缩小索引文件的大小,用户在设计表结构的时候也可以对文本列依据此特性进行灵活设计。
1
|
mysql>create index ind_company2_name on company2(name(4));
|
--当中company表名ind_company2_name索引名
MySQL怎样使用索引
一、使用索引
(1)对于建立的多列索引。仅仅要查询的条件中用到最左边的列。索引通常就会被使用。例如如下建立一个复合索引。
1
|
mysql>create index ind_sales2_com_mon on sales2(company_id,moneys);
|
而后按company_id进行查询。发现使用到了复合索引
1
|
mysql>explain
select
* from sales2 where company_id=2006\G
|
使用如下的查询就没有使用到复合索引。
1
|
mysql>explain
select
* from sales2 where moneys=1\G
|
(2) 使用like的查询,后面假设是常量并且仅仅有%号不在第一个字符。索引才可能会被使用。例如如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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)
|
例如如下这个使用到了索引。而如下样例可使用索引,差异就在于“%”的位置不一样,上面的样例是吧“%”放在了第一位,而如下的样例则没有
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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将使用索引。例如如下
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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之间,查询时使用索引就不是很是好
1
|
mysql>
select
* from table_name where key_part1>1 and key_part<90;
|
(2)假设使用MEMORY/HEAP表并且where条件中不使用“=”进行索引列。那么不会用到索引。Heap表仅仅有在“=”的条件下会使用索引。
(3)用or切割开的条件。假设or前的条件中的列有索引,然后面的列中没有索引,那么涉及的索引都不会被用到。
1
2
3
4
5
6
7
|
mysql>show index from sales\G
*************************** 1. row ***************************
……
key_name: ind_sales_year
seq_in_index:1
Column_name: year
……
|
从上面可以发现仅仅有year列上面有索引。
来看例如如下的运行计划。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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採用。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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列上有索引,但是也没实用到。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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语句就可以正确使用索引。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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的值高则意味着查询执行低效。并且应该创建索引补救。
1
2
3
4
5
6
7
8
9
10
11
12
|
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)
|
两个简单有用的优化方法
分析表的语法例如如下:(检查一个或多个表是否有错误)
1
2
3
4
5
6
7
8
9
|
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表起做用。
1
2
3
4
5
6
7
|
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表非惟一索引:
1
2
3
|
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表非惟一索引:
1
2
3
4
5
6
7
|
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主键存储顺序保存的
1
2
|
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倍)
1
2
3
|
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时
1
2
3
|
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时
1
2
3
|
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时
1
2
3
|
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时
1
2
3
|
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语句,这样可以大大缩短客户与数据库的链接、关闭等损耗。
可以使用insert delayed(当即运行)语句获得更高的效率。
将索引文件和数据文件分别存放不一样的磁盘上。
可以添加bulk_insert_buffer_size 变量值的方法来提快速度。但是仅仅对MyISAM表使用当从一个文件里装载一个表时,使用LOAD DATA INFILE。这个一般比使用很是多insert语句要快20倍。
优化group by语句
假设查询包括group by但用户想要避免排序结果的损耗,则可以使用使用order by null来禁止排序:
例如如下没有使用order by null来禁止排序
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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的效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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)替代)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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()对当前应用的表进行分析,改函数可以对数据表中列的数据类型提出优化建议,用户可以依据应用的实际状况酌情考虑是否实施优化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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.又一次生成一个新表
Mysqlserver优化
myisam读锁定
1.
lock table t1 read
2.开启还有一个mysql链接终端,接着去尝试:
select * from t1
3.再insert、update和delete t1这张表。你会发现所有的数据都停留在终端上没有真正的去操做
4.读锁定对咱们在作备份大量数据时很实用.
mysqldump -uroot -p123 test >test.sql
myisam写锁定
1.
lock table t1 write
2.打开还有一个mysql终端,尝试去select、insert、update和delete这张表t1,你会发现都不能操做,都会停留在终端上。仅仅有等第一个终端操做完成,第二个终端才干真正运行.
3.可见表的写锁定比读锁定更严格
4.普通状况下咱们很是少去显式的去对表进行read 和write锁定的,myisam会本身主动进行锁定的.
Mysqlserver优化
二进制日志
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%"
socket问题
mysql socket没法登陆
1. 有时登陆mysql时提示不能用socket登陆,此时可以换成tcp方式去登陆,但是可以測试时可以这样用。但是必须要在php去用以前把这个事情攻克了.
1
2
3
4
5
6
|
[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服务时产生的
rootpassword丢失
rootpassword丢失破解
1
2
3
4
5
6
7
8
9
10
11
|
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");
//和第五步同样,均可能成功改动password
|