MySQL基礎操作&&常用的SQL技巧&&SQL語句優化


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

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM