該數據庫有三個在線重作日誌組。經過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
|