基礎操作
一:MySQL基礎操作
1:MySQL表復制
復制表結構 + 復制表數據
create
table
t3
like
t1;
--創建一個和t1一樣的表,用like(表結構也一樣)
insert
into
t3
select
*
from
t1;
--t1的數據全部拿過來,注意是表結構一致才select* ,否則選擇相應的的字段列插入
create
table
t1(
id
int
unsigned
not
null
auto_increment
primary
key
,
name
varchar
(30)
);
2:MySQL索引(
create
不能創建主鍵索引,得用
alter
,建議全部用
alter
創建索引)
*設置主鍵后默認就是主鍵索引
一:
alter
table
用來創建普通索引,
unique
索引或
primary
key
索引
普通索引:
alter
table
t1
add
index
in_name(
name
)
--t1表中的那么字段添加索引名為in_name
唯一索引:
alter
table
t1
add
unique
(
name
)
--不給名字,默認是字段名
alter
table
t1
add
unique
un_name(
name
)
主鍵索引(自增才有意義):
alter
table
t1
add
primary
key
(id)
主鍵索引不是自增記得改成自增:
alter
table
t1
modify
id
int
unsigned
not
null
auto_increment;
查看:show
index
from
t1;
刪除:
alter
table
t1
drop
index
in_name;
@*刪除主鍵索引單獨處理*
二:
alter
table
table_name
drop
index
index_name
alter
型刪除索引:
alter
table
t1
drop
index
in_name;
@*刪除主鍵索引*:
注意:刪除主鍵索引的時候,如果你的主鍵索引是自增(如:id)刪除是會報錯的
實在想玩的話就把主鍵的auto_increment消掉
alter
table
t1
modify
id
int
unsigned
not
null
;
接着刪除主鍵:
alter
table
t1
drop
primary
key
;
改成自增:
alter
table
t1
modify
id
int
unsigned
not
null
auto_increment;
三:
create
index
(不常用學習下,不能對主鍵索引操作,只能操作普通和唯一索引)
*創建普通索引:
create
index
in_name
on
t1(
name
);
--將t1表中的那么字段添加為普通索引
查看索引: show
index
from
t1;
刪除索引:
drop
index
in_name
on
t1;
--t1表中的in_name索引刪除
->在做唯一索引之前字段不能有重復值,否則創建不成功
*創建唯一索引:
create
unique
index
un_name
on
t1(
name
);
四:刪除
create
創建的索引:
drop
index
drop
index
in_name
on
t1;
3:MySQL視圖
定義:視圖是一個虛擬表,其內容由查詢定義,是根據建立視圖的sql語句拿到的數據保存在一張表中而創建的表-視圖
*根據從表里面拿出來的數據而創建出來的一張表
創建視圖:
create
view
v_t1
as
select
*
from
t1
where
id>4
and
id<11;
作用:
如果 t1表里的數據某條記錄被刪除了,那么視圖v_t1表的對應數據也會刪除,類似主從(主表無則從無)
所以:視圖也可以充當一個中間表:查數據的時候可以不去查主t1 去查視圖表v_t1
*視圖表示依賴於,創建時sql的表t_name,如果表t_name損壞的了(刪除了),對應的視圖將會發生錯誤不能使用
查看視圖:show tables;
刪除視圖:
drop
view
v_t1;
視圖幫助信息:?
view
;
4:MySQL內置函數
字符串函數:
select
concat(
"hello"
,
"word"
); 鏈接字串 ->hello world
lcase(
"MYSQL"
) 轉換成小寫
ucase(
"mysql"
) 轉換成大寫
length(
"leyangjun"
) string長度
ltrim(
" userName"
) 去除前端空格
rtrim(
"userName "
) 去除后端空格
repeat(
"linux"
,
count
) 重復
count
次(
select
repeat(
'd'
,2);重復輸出2次dd)
replace
(str,search_str,replace_str) 在str中使用replace_str替換search_str
substring
(str,position[length]) 從str的position開始,取length個字符串->
substring
和 substr一樣
select
substr(
"leyangjun"
,1,5); 從第一個開始取5個字符串
space
(
count
) 生成
count
(數字)個空格
數學函數
bin(decimal_number) 十進制轉二進制(
select
bin(120);)
ceiling(number2) 向上取整(
select
ceiling(10.10);
--->11)
floor(number2) 向下取整(
select
ceiling(10.10);
--->10)
Max
(列) 取最大值
MIN
(列) 取最小值
sqrt(number2) 開平方
rand() 返回0-1內的隨機值
日期函數:
curdate(); 返回當前日期
curtime(); 返回當前時間
now(); 返回當前的日期和時間
unix_timestamp(
date
) 返回
date
的unix時間戳
from_unixtime() 返回unix時間戳日期值
week(
date
) 返回日期
date
為一年中的第幾周
year
(
date
) 返回日期中的年份
datediff(expr,expr2) 返回起始時間expr和結束時間expr2間隔天數
select
datediff(
"2014-08-03"
,
"2014-08-04"
);
5:MySQL預處理語句
一:設置一個預處理語句:
prepare
stmt1
from
'select * from t1 where id>?'
;
二:設置一個變量:
set
@=i1;
三:執行stmt1預處理:
execute
stmt1 using @i;
設置@i=5
set
@i=5;
execute
stmt1 using @i;
刪除預處理:
drop
prepare
stmt1;
應用場景:比如你是老板我要看1,2,3,4,5,6、、、、12月份入職人員的情況
*就可以把SQL做成預處理,這樣就不需要每次去請求MySQL直接傳個值就可以(MySQL是將預處理的SQL儲存起來,用的時候傳值直接就執行,就不需要每次請求連接MySQL在重新執行)
6:MySQL事務處理(增刪改查后只要沒有
commit
,全可以回滾)
*myisam引擎不支持事務,innodb(支持外鍵和事務)才支持事務
修改表引擎方法:
alter
table
t1 engine=innodb
一:事務操作
查看是否自動提交:
select
@@autocommit;
關閉自動提交
set
autocommit=0;
delete
from
t1
where
id>5; 數據只是臨時刪除,如果
commit
就真正的執行刪除語句
rollback
; 只要沒
commit
還原剛才刪除的數據
commit
;
二:還原點的使用:
insert
into
t1
values
(
"user4"
);
savepoint p1;
insert
into
t1
values
(
"user5"
);
savepoint p2;
insert
into
t1
values
(
"user6"
);
savepoint p3;
--3個數據已經插進去啦,能后你覺得user6不要,你就找到還原點 savepoint p2就行
rollback
to
p2;
--還原到P2 user6不要
commit
;
7:MySQL存儲(可以認為是自定義的函數)
創建一個存儲:
\d //
create
procedure
p1()
begin
set
@i=0;
while @i<10 do
insert
into
t2(
name
)
values
(concat(
"user"
,@i));
--這里可以做增刪改查。。。都行
set
@i=@i+1;
end
while;
end
;
//
執行一個存儲:
\d ;
call p1();
查看存儲:
show
procedure
status;
show
create
procedure
p1\G
--查看p1存儲的基本信息
8:MySQL觸發器(自動執行)
*查詢沒有必要做觸發器!:
select
*
from
t1
union
select
*
from
t2;
一:增加觸發器
\d //
創建一個名字為tg1的觸發器,當向表中插入數據時,就向t2表中插入一條數據
create
trigger
tg1 before
insert
on
t1
for
each row
begin
insert
into
t2(id)
values
(new.id);
--new.id 比如向t1表里面插入了id=4的 能后new.id=4 直接復制到這
end
//
准備好t1 表 和 t1表
向t1表中插入多條數據
查看:show triggers;
刪除觸發器:
drop
trigger
t2;
二:刪除觸發器(注意下:刪除的時候2個表的值一定要對稱,比如t1:1,2,3 t2:11,12,13這么刪除是不行會報錯,以一定要對稱
比如t1和t2表都有user1,這樣刪除就是沒問題 )
\d //
create
trigger
tg2 before
delete
on
t1
for
each row
begin
delete
from
t2
where
id=old.id;
--插入的時候里面沒有這個值叫new.id 提前有的值叫old.id
end
//
三:更改觸發器:
create
trigger
tg3 before
update
on
t1
for
each row
begin
update
t2
set
id=new.id
where
old.id;
--(update t1 set name="leyangjun"-new.id where name="zhangfei"-old.id)
end
//
9:重排auto_increment值
MySQL數據庫自動增長的ID如何恢復:
清空表的時候,不能用
delete
from
tableName;
而是用
truncate
tableName;
這樣auto_increment就恢復成1了
或者清空內容后直接用
alter
命令修改表:
alter
table
tableName auto_increment=1;
場景:
1:t1表里面有id字段分別對應 1,2,3,4,5,6,7,8,9的記錄,
2:能后我們
delete
刪除,能后在插入數據,你會發現插入的時候是從10,11,12,13.....開始而不是1
3:清空的時候我們執行下這個歸檔為1即可:
alter
table
tableName auto_increment=1;
4:能后在插入的時候就是從1開始的啦
====================================================================================================================================
2.常用的SQL技巧
一:正則表達式的使用
--(注意匹配到了是1 沒有則為0)
select
"linux is very ok"
regexp
".*"
;
--匹配所有
select
"linux is very ok"
regexp
"^linux"
--匹配以linux為開頭的
->通用的一些:
^ 在字符串的開始處進行匹配 a? 匹配1個或0個
$ 在字符串的末尾處進行匹配 a1|a2 匹配a1或a2
. 匹配任意單個字符,包括換行符號 a(m) 匹配m個a
[...] 匹配括號內的任意字符 a(m,) 匹配至少m個a
[^...]匹配不出現括號內的任意字符 a(m,n) 匹配m到n個a
a* 匹配0個或多個a(包括空串) a(,n) 匹配0到n個a
a+ 匹配1個或多個(不包括空串) (...) 將模式元素組成單一元素
匹配郵箱(根據匹配.,正則效率高):
--但是正則比like的缺點就是更消耗程序消耗資源
1使用正則表達式“$” 和 [...] 進行匹配:
select
name
,email
from
leyangjun
where
email REGEXP
"@163[.,]com$"
;
--[.,]匹配. 或 ,
2使用
like
方式查詢:
select
name
,email
from
leyangjun
where
email
like
"@163.com"
or
email
like
"%@163,com"
;
二:巧用rand()提取隨機行(
select
rand()*100)
MySQL數據庫中隨機函數rand()是取一個0-1之間的數,利用這個函數一起
order
by
能夠把數據隨機排序
select
*
from
stu
order
by
rand();
--隨機排序
select
*
from
stu
order
by
rand() limit 3;
--抽樣調差可以玩
三:利用
group
by
的
with
rollup
子句統計
*注意:
with
rollup
不可以和
order
by
同時使用
使用
group
by
的
with
rollup
子句可以檢索出更多的分組聚合信息
select
cname,pname,
count
(pname)
from
demo
group
by
cname,pname;
使用
with
rollup
可以統計出更多的信息:
select
name
,pname,
count
(pname)
from
demo
group
by
cname,pname
with
rollup
;
--會吧算出來的數加起來 比如:bj hd 5 sh hd 4 最后會增加個null 列 總數9
四:用
bit
group
functions做統計(用的少),就是二進制進行運算
*只有聚合分組的時候這個2個函數才會有意義。
在使用
group
by
語句時可以同時使用bit_and 、bit_or函數來完成統計工作。這兩個函數的
作用主要是做數值之間的邏輯運算。
2個函數把數值轉成二進制
bit_or或運算->二進制的值-就是0和1(0,1=1 0,0=0 1,1=1):
select
id,bit_or(kind)
from
order_rab
group
by
id;
bit_and是&&運算(只有1,1=1,其他值全為0):
select
id,bit_and(kind)
from
order_rab
group
by
id;
五:使用外鍵需要注意的問題(不鼓勵在MySQL中使用外鍵)
外鍵:我這個表的字段是楞一個表的主鍵,依賴關系
create
table
temp
(id
int
,
name
char
(20),
foreign
key
(id)
references
outTable(id)
on
delete
cascade
on
update
cascade
);
*注意:innodb類型的表支持外鍵,myisam類型的表,雖能創建外鍵可以成功,但是不起作用,主要原因是不支持外鍵。
六:MySQL中help的使用
在MySQL中有很多命令如果不記得,要使用MySQL的提示下的操作也就是 ?:
1:?% 可以獲得多有的MySQL里面的命令,這個事最多的,建議不使用下面
2:?
create
3:?opti% 以為記不住optimize的全稱,這個時候可以用%來代替
4:?reg% 獲取了記不住的regexp的用法
5:? contents; 查看所有幫助信息 -> 可以得到所有的幫助大綱,通過這個目錄在用?繼續往下細查
比如:?contents;
? functions; 查看所有的函數,就是?contents得出來的functions
? string funtions; .......
===============================================================================================================================
3.SQL語句優化
一:優化SQL語句的一般步驟
1:通過show status命令了解各種SQL的執行頻率
格式:show session|
global
status;
session:(默認)表示當前連接
global
:表示自數據庫啟動至今
show status;
show
global
status;
show status
like
'Com_%'
;
--一般只差以Com開頭的東西
show
global
status
like
'Com_%'
;
重點跟蹤這幾個值(登入以來,所有的操作都會有記載):
show status
like
"Com_insert%"
;
--查看到:總共插了多少條 insert_select方式插入使用了幾次
show status
like
"Com_select%"
;
--登入以來,插入了幾次
show status
like
"Com_update%"
;
show status
like
"Com_delete%"
;
只針對於innoDB存儲引擎的(記載的是影響行數):
SQL:show status
like
"innodb_rows%"
;
--就可以查看到下面的內容
InnoDB_rows_read執行
select
操作的次數
InnoDB_rows_updated執行
update
操作的次數
InnoDB_rows_inserted執行
insert
操作的次數
InnoDB_rows_deleted執行
delete
操作的次數
其他:
sql: show status
like
"connections"
;
connections 鏈接MySQL的數量(包括你鏈接成功或不成功都會記載)
Uptime 服務器已經工作的秒傷
Slow_queries 慢查詢次數
show variables
like
"%slow%"
; 查看是否開啟慢查詢
OFF
關閉(默認慢查詢文件等詳細信息)
show variables
like
"%long%"
; 查看默認慢查詢的時間默認是10s
*2:定位執行效率較低的語句(解析sql)
可以查出:有沒有用索引啊 單表查還是多表查 還是嵌套查詢啊。。。,看這幾個值既能分析出來
*重點查看的是 row:8 影響行數
ref:
null
如果你表建立的所有,ref會推薦你使用什么索引
explain
select
*
from
tables
where
id=10 \G; 可以用 \G排下
desc
select
*
from
tables
where
id=10;
二:索引問題
索引是數據庫優化中最常見也是最重要的手段之一,通過索引通常可以幫助用戶解決大多數的SQL性能問題。
1:索引的存儲分類
MyISam存儲引擎的表的數據和索引是自動分開存儲的,各自是獨立的一個文件(3個文件 frm-表結構文件 d-數據文件 i-索引文件)
InnoDB存儲引擎的表數據和索引是存儲在同一個表空間里面的,但可以有多個文件組成(默認是共享表空間,所以是同一個文件)
MySQL目前不支持函數索引,但是能對列的前面某一部分進行索引,例如
name
字段,可以只取
name
的前4個字符進行索引,
這個特性可以大大縮小索引文件的大小,用戶在設計表結構的時候也可以對文本列根據此特性進行靈活設計。
SQL:
create
index
ind_company2_name
on
company(
name
(4));
--其中company表名ind_company2_name索引名 且 針對name4個字符進行索引
2:MySQL如何使用索引
索引用於快速查找在某個列中有一特定值的行。對相關列使用索引是提高
select
操作性能的最佳途徑。
一:使用索引:
(1):對於創建的多列索引,只要查詢的條件中用到左邊的列,索引一般就會被使用。
如下創建個復合索引:
create
index
ind_sales2_com_mon
on
sales2(commpany_id,moneys);
能后按company_id進行查詢,發現使用到了復合索引
explain
select
*
from
sales2
where
commpany_id=100 \G;
使用下面的查詢就沒有使用到復合索引
explain
select
*
from
sales2
where
moneys=1 \G;
(2):
like
使用索引要注意,有時候用不上看你
like
是怎么寫的,%號放后面就可以用上索引
索引什么時候用不上(已經建了索引sql時候沒用上)
使用
like
的查詢,后面如果是常量並且只有%號不在第一個字符,索引才可能會被使用,如下:
explain
select
*
from
commpany2
where
name
like
"%3%"
\G;
--沒用上
explain
select
*
from
commpany2
where
name
like
"3%%"
\G;
--用上啦
(3):如果對大額文本進行搜索,使用全文索引而不使用
like
"%...%"
;
(4):如果列名是索引,使用column_name
is
null
將使用索引,如下:
explain
select
*
from
commpany2
where
name
is
null
\G
--查找那么是null的值,也會用到索引
explain
select
*
from
commpany2
where
name
is
not
null
\G
--也會用到索引
二:存在索引但不使用索引(索引沒用上)
(1):如果MySQL估計使用索引比全表掃描更慢,則不適用索引。列如:如果列key_part1均勻分布在1到100之間,查詢時使用索引就不是很好
select
*
from
tableName
where
key_part1>1
and
key_part<90;
(2):如果使用memory/heap 表並且
where
條件中不適用
"="
進行索引列,那么不會用到索引。heap表只是有在
"="
的條件下回使用索引。
(3):用
or
分割開的條件,如果
or
前的條件中的列有索引,而后面的列中沒有索引,那么涉及的所有都不會被用到。
show
index
from
sales \G
****注意******
如果你的sql語句中使用了
where
and
什么 ,
or
什么的時候,
and
/
or
前面和后面的字段必須都要加索引,如果只一個加索引那么
where
查詢后面的整個索引將會失效->導致整個索引都用不上,最終索引是沒有意義的
從上面可以發現只有
year
列上面有索引,如:
explain
select
*
from
sales
where
year
=2001
or
country=
'China'
\G
(4):如果不是索引列的第一部分,如下列子:可見雖能在moeney上建有復合索引,但是由於money不是索引的第一列,
那么查詢中這個索引也不會被MySQL使用
explain
select
*
from
sales2
where
moneys=1 \G
(5):如果
like
是以為%開始,可能
name
字段有索引,但是由於條件中
like
的值得
"%"
號在第一位MySQL也不會使用索引
(6):如果列類型是字符串,但是在查詢的時候把一個數值型常量給了一個字符型的列名
name
,
那么雖能
name
列上有索引,但是也沒有用到
explain
select
*
from
company2
where
name
=294 \G
--能找到記錄你輸入294的會自動轉成'294',但是不會使用索引
三:查看所有使用情況
如果索引正在工作,Handler_red_key(讀取索引的次數) 的值將很高。
Handler_read_rnd_next的值高則意味着查詢運行低效,並且應該建立索引補救。
show status
like
'Handler_red%'
;
--Handler_read_rnd_next這個值偏高得話就得結合慢查詢日志,看看那個sql慢 進而來建索引
三:兩個簡單使用的優化方法
對於大多數開發人員來說,可能只希望掌握一些簡單實用的優化方法,對於更多復雜的優化,更傾向交給作業DBA來做
(1):定期分析表和檢查表
*分析的語法如下:(檢查一個表或多個表是否有錯誤,比如視圖:視圖依賴一個主表,主表刪除了,能后你用這個命令查看你的視圖表就會報錯)
check
table
table_name;
(2):定期優化表
優化表的語法格式:
就是優化表空間->刪除等操作一些碎片和空洞清理出去
optimize
table
table_name;
--如果已經刪除了表的一大部分,或者已經對含有可變長度的表進行了很多的改動,則需要
做定期優化。這個命令可以將表中的空間碎片進行合並,但是次命令只對myiam bdb和innodb表起作用。
四:常用SQL的優化
(1):大批量插入數據
一:當用
load
命令導入數據的時候。適當設置可以提高導入的速度。 ?
load
data
導出 導入數據 新方法:
select
name
from
t1
into
outfile
"/tmp/test.txt"
;
--將表t1 name字段數據導出到文件里去
load
data infile
"/tmp/test.txt"
into
table
t1(
name
);
--清空表t1,在將剛才導出來的t1表name字段的數據值在導入t1表中的name中去
二:對於myisam存儲引擎的表,可以通過以下方式快速的導入大量的數據。
注意:一般指關閉非唯一索引,以為怕導入的時候有相同的值就監控不到啦
插入完后再一起做索引,否則每次插入一條索引文件也插入一條
alter
table
table_name disable keys
load
data .....
alter
table
table_name enable keys
-->disable keys 和 enable keys 用來打開或關閉myisam表非唯一索引(除了住建索引)的更新,可以提高速度 innodb 無效的哦
->1:使用打開或關閉MyISAM非唯一索引(表已經建立了索引):
alter
table
table_Name disable keys;
--關閉
load
data infile
"/tmp/test.txt"
into
table
t1(
name
);
--導入數據后在統一價索引
alter
table
table_Name enable keys;
--開啟,統一加索引
->2:關閉唯一索引,可以提高導入效率(保證你數據不會有問題,不會出現沖突值、重復啥的)
在導入數據前先執行
set
unique_checks=0,關閉唯一性效驗,在導入數據后先執行
set
unique_checks=1,恢復唯一效驗,可以提高導入效率
SQL:
set
unique_checks=0;
load
data infile
"/tmp/test.txt"
into
table
t1(
name
);
set
unique_checks=1;
三:針對於Innodb類型表數據導入的優化
1:因為innodb表的按照主鍵順序保存的,所以將導入的數據主鍵的順序呢排序,可以有效地提高導入數據的效率。
使用test3.txt文本是按表film_test4主鍵存儲順序保存
load
data infile
"/tmp/test.txt"
into
table
film_test4;
2:關閉自動提交可以提高導入效率
在導入數據前先執行
set
autocommit=0,關閉自動提交事務,在導入數據后先執行
set
autocommit=1,恢復自動提交,可提高效率。
set
autocommit=0;
load
data infile
"/tmp/test.txt"
into
table
film_test4;
set
autocommit=1;
四:優化
insert
語句:
盡量使用多個值表的
insert
語句,這樣可以大大縮短客戶與數據庫之間的鏈接、關閉損耗。
可以盡量使用
insert
delayed(馬上執行)語句得到更高得效率。
將索引文件盒數據文件分別存放不同的磁盤上。
可以增加bulk_inser_buffer_size變量值得方法來提高速度,但是只是對myisam表使用。
當從一個文件中裝載一個表時,使用
load
data infile,這個通常比使用很多
insert
語句要快20倍。
插入的時候可以:
insert
into
t1(
name
)
values
(
"user1"
),(
"user2"
),(
"user3"
),(
"user4"
);
--程序邏輯里面插入的時候盡量批量插入,要不插一次鏈接、關閉一次MySQL
五:優化
group
by
語句:
如果查詢包含
group
by
但用戶想要避免排序結果的損耗,則可以使用
order
by
null
來禁止排序:
如下沒有使用
order
by
null
來禁止排序
explain
select
id,
sum
(moneys)
from
table_Name
group
by
id \G
--默認是升序排序,desc sql 看下 Extra:using temporary:using filesort
如下使用
order
by
null
來禁止排序(作用:最低的消耗資源)
explain
select
id,
sum
(moneys)
from
table_Name
group
by
id
order
by
null
\G
--desc sql 看下 Extra:using temporary
六:優化嵌套查詢(表都建立啦索引的前提下)
下面是采用嵌套查詢的效果(可以使用更有效的鏈接查詢(
join
)替代)
嵌套查詢(效率極低,多表的話只會用到一張表的索引)
--里面的能用到索引外面的用不到索引
explain
select
*
from
table_Name1
where
company_id
not
in
(
select
id
from
table_Name2)\G
--desc sql看下你會發現如果2張表都建立索引,你會發現改嵌套查詢table_Name2會用到索引查詢,table_Name1不會
替代(都使用到索引)
explain
select
*
from
table_Name1
left
join
table_Name2
on
table_Name1.company_id=table_Name2.id
where
table_Name1.company_id
is
not
null
\G
鏈接查詢優秀嵌套查詢(上面):
desc
select
* t1.*
from
t1,t2
where
t1.id=t2.uid \G
--這個sql 2張表在查詢的時候都會用到索引
左右鏈接查詢也會同時用到索引:
desc
select
t1.*
from
t1
left
join
t2
on
t1.id=t2.uid
where
t2.uid
is
not
null
\G
===============================================================================================================================
4.MySQL數據庫優化(主要針對表)
一:優化表的類型
只能考認為的去對表結構進行優化
二:通過拆分提高表的訪問效率
大存儲量解決:1:分庫分表 2:分區
主要目的:1:減少表的記錄數 2:減少對操作系統的負擔壓力
三:使用中間表提高統計查詢速度
中間表生成:1:
view
視圖 2:重新生成一個新表
比如:有個存儲帖子的表,能后我只是取前3條的熱門貼,如果用
select
*
from
tiezi
where
id<4; 會全表掃描,性能低
1:就是建立視圖(推薦使用視圖)
create
view
zj_view
as
select
*
from
tiezi
where
id<4;
--查詢的時候直接查視圖表
2:就是建立個表(不靈活)
create
table
zj
like
tizi;
insert
into
zj
select
*
from
tiezi
where
id<4;
--將數據插入到zj表,查詢的時候查這個表即可
===============================================================================================================================
5.Myisam表鎖
一:myisam讀鎖定(所有人只有讀權限不能進行增刪改)
1:lock
table
t1
read
2:開啟另一個MySQL鏈接端,接着去嘗試:
select
*
from
t1;
3: 再
insert
、
update
和
delete
t1這張表,你會發現所有的執行的sql都停留在終端上沒有真正的去操作執行,直到解鎖為止自動就執行
4:讀鎖定對我們在多備份大量數據時非常有用
mysqldump -uroot -p123456 test>test.sql
解鎖:unlock tables;
二:myisam寫鎖定(只有本人進行增刪改查,其他人不能進行任何操作)
1:lock
table
t1 write
2: 打開另一個mysql終端,嘗試
select
、
insert
、
update
、
delete
這個表t1,你會發現都不能操作,
都會停留在終端上,只有等一個終端操作完畢,解鎖后第二個終端才能真正執行
3:可見表的寫鎖比讀鎖更嚴格
4:一般情況下我們很少嘗試的取對表進行
read
、write鎖定的,myisam會自動進行鎖定的
解鎖:unlock tables;
--全部解鎖
===============================================================================================================================
6.MySQL服務器優化
一:四種字符集問題(盡量統一設置utf8)
sql: \s 查看
服務器字符集:server characterset: utf8
數據庫字符集:Db characterset:utf8
客戶端字符集:client characterset:utf8
鏈接字符集:conn. characterset:utf8
怎么設置字符集:mysql配置文件中找到:
[client]
default
-
character
-
set
= utf8
--控制 客戶端字符集 和 鏈接字符集
[mysqld]
character
-
set
-server = utf8
--控制服務器的字符集和數據庫字符集 以及繼承下來的表字符集
collation-server = utf8_general_ci
--控制校驗字符集(用途:比如 order by來排序,數據庫這么知道這么排序就是靠這個)
能后重啟mysql: pkill mysqld
--殺死進程
pstree |grep mysqld
--看mysql進程還在不在
/mysql/bin/mysqld_safe
--user=mysql & 重啟
!ps
--查看進程
查看校驗字符集:
show
character
set
;
--一堆校驗字符集
二:
binary
log 日志問題
查看bin log日志:
show variables
like
"%bin%"
;
--看log_bin 是否開啟 ON表示開啟,;inux默認是開啟的
開啟log-bin日志:
配置文件中打開:log-bin=mysql-bin
三:slow log 慢查詢日志問題
查看慢查詢是否開啟:
show variables
like
"%slow%"
;
--看slow_query_log 是否開啟
--慢查詢日志保存地址 slow_query_log_file -> E:\wamp\bin\mysql\mysql5.5.20\data\asus-PC-slow.log
show variables
like
"%long%"
;
--查看慢查詢時間10s,long_query_time
開啟和設置慢查詢時間:
配置文件里[mysqld]下添加就好:
log_slow_queries=E:/data/slow.log
long_query_time=5 大於5秒的SQL就會被記載到slow.log文件中
四:socket問題
解釋:socket是php程序鏈接操作mysql時候就要用mysql.sock文件要找到這個端口
如果把這個文件刪除啦也就是說php就不知道往那台機器那個端口去連
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
port=3306
socket=/tmp/mysql.sock
skip-locking
mysql socket無法登陸:(臨時急救的辦法,php是用不了的)
1:有時候mysql登錄是提示不能用socket登錄,此時可以換成tcp方式去登錄,但是可以測試時候可以這樣用
但是必須要php去用之前把這個事情解決了
mysql -uroot -p123456
--protocol tcp -hlocalhost; --這樣就可以登錄,這樣就不用mysql.socket來登錄,而mysql.socket是啟動mysqld服務時產生的
*能后這個方式登錄進來之后,你在重啟下mysql服務,mysql.socket文件會自動建立
五:root密碼丟失
破解:(破解思路:跳過授權表,進去后能后在務修改密碼)
1:server mysqld stop
2: mysqld_safe
--skip-grant-tables --user=mysql & ->跳過授權表mysql.user和mysql.db這些表
3:mysql -uroot
4:
set
password
=
password
(
"leyangjun"
);
--用這條語句結果報錯,就是因為加了--skip-grant-tables
5:
update
user
set
password
=
password
(
"leyangjun"
)
where
user
=
'root'
and
host=
'localhost'
;
--這個sql就可以搞定下面2個演示
6:
set
password
for
root@localhost=
password
(
"leyangjun"
);
7:
set
password
=
password
(
"leyangjun"
);
--和第6步一樣,都可以成功修改密碼,password("leyangjun")是用PW進行加密比md5更嚴格
能后重新啟動下mysql服務即可
