程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL性能優化(二)

MySQL性能優化(二)

編輯:MySQL綜合教程

MySQL性能優化(二)


1.MySQL基礎操作
	一: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服務即可

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved