CentOS7环境下MySQL踩坑记
?
1.啟動/配置/編碼等問題
安裝包放在opt目錄下
安裝:rpm -ivh rpm 軟件名
如果安裝時,與某個軟件 xxx沖突,則需要將沖突的軟件卸載掉:
yum -y remove xxx
?
修改密碼:
/usr/bin/mysqladmin -u root password 'new-password' /usr/bin/mysqladmin -u root -h localhost.localdomain password 'new-password'驗證安裝是否成功:mysqladmin --version
[root@localhost opt]# mysqladmin --version mysqladmin Ver 8.42 Distrib 5.5.60, for Linux on x86_64啟動:service mysql start
關閉:service mysql stop
重啟:service mysql restart
重啟計算機:reboot
重啟計算機后可能出現問題,大多數是沒有啟動服務。
啟動服務,設置開機自啟動:chkconfig mysql on
登錄MySQL:
mysql -u -root -p
出現錯誤:
先停止MySQL服務:service mysqld stop
再啟動:service mysql start
再登陸就ok了
很詭異,這是目前這次遇到的情況。
?
查看數據庫安裝目錄: ps -ef|grep mysql
數據存放目錄:datadir=/var/lib/mysql
pid文件目錄:pid-file=/var/lib/mysql/localhost.localdomain.pid
核心目錄:
安裝目錄:/var/lib/mysql
配置文件:/usr/share/mysql
命令目錄:/usr/bin (mysqladmin,mysqldump 等命令)
啟停腳本:/etc/init.d/mysql?
?
MysQL配置文件:
my-huge.cnf 高端服務器 1-2G
my-large.cnf 中等規模
my-medium.cnf 一般
my-small.cnf 較小
但是,以上配置文件mysql默認不能識別,默認只能識別 /etc/my.cnf
采用my-huge.cnf:
執行命令:cp /usr/share/mysql/my-huge.cnf? /etc/my.cnf
注意:mysql5.5默認配置文件: /etc/my.cnf
? ? ? ? ? ?mysql5.6默認配置文件: /etc/mysql-default.cnf
?
mysql字符編碼:
登錄mysql,模糊查詢,執行:show variables like '%char%';
發現部分編碼不是utf-8,需要統一設置為utf-8
設置編碼:
執行命令:vi /etc/my.cnf
往下拉找到這個[mysql],添加:default-character-set=utf8
再找到[client]:
再找到[mysqld]:
character_set_server=utf8
character_set_client=utf8
collation_server=utf8_general_ci
重啟mysql:service mysql restart
再登陸mysql,執行:show variables like '%char%';
注意:修改編碼之后只對“之后”創建的數據庫生效
同時發現:vi /etc/my.cnf 可以修改密碼和默認端口,如下
此外:mysql清屏: ctrl+L? 或者 system clear
?
2.MySQL分層/存儲引擎
MySQL邏輯分層:連接層,服務層,引擎層,存儲層。
InnoDB(默認):事務優先,使用行鎖(一次鎖一行數據),適合高并發操作
MyISAM:性能優先,使用表鎖(一次鎖一張表里的數據)
client端進行select,直接連接連接層,連接層調用服務層的接口,經過SQL優化器優化之后 ,傳到引擎層進行選擇引擎。
查詢數據庫引擎:
支持哪些引擎: show engines;
查詢當前使用引擎:show variables like '%storage_engine%';
指定數據庫對象的引擎:
create table tb( id int(4) auto_increment, name varchar(5), dept varchar(5), primary key(id) )ENGINE=MyISAM AUTO_INCREMENT=1 default charset=utf8;?
3.SQL解析過程/索引/B樹
SQL優化
誘因:性能低、執行時間太長、等待時間太長、SQL語句欠佳(連接查詢)、索引失效、服務器參數設置不合理(緩沖區、線程數)
- SQL:
- 編寫過程:select? dinstinct.. from ..join .. on ..where ..group by .. having .. order by .. limit ..
- 解析過程:from ..on ..join ..where ..group by ...having ..select? dinstinct .. order by..limit ..
- SQL 優化,主要就是在優化索引
- 索引:相當于書的目錄,關鍵字為?index?,是幫助MySQL高效獲取數據的數據結構,索引是數據結構(樹:B樹(MySQL默認)、哈希樹)。
? ? ? ?
- 索引優勢:提高查詢效率(降低IO使用率),降低CPU使用率(..order by age desc,因為B樹索引本身就是一個排好序的結構,排序時可以直接使用)
- 索引的弊端:
- 本身很大,可以放在內存/硬盤(通常為硬盤)?
- 索引不是所有情況都適用:
- 少量數據;
- 頻繁更新的字段;
- 很少使用的字段;
- 索引會降低增刪改的效率
- 3層B樹可以存放上百萬條數據
- B樹一般指的是B+樹,B+樹數據全部存放在葉節點中
- B+樹中查詢任意的數據次數:n次(B+樹的高度)
?
索引:
分類:
- 單值索引:單列,比如age;一個表可以有多個單值索引,比如name,age
- 唯一索引:不能重復,比如id。
- 復合索引:多個列構成的索引(相當于書的二級目錄)
創建索引:
- 方式一:
create? 索引類型? 索引名? on? 表(字段)
以前文創建的tb表為例子:
創建單值索引:create index dept_index on tb(dept);
創建唯一索引:create unique index name_index on tb(name);
復合索引:create index dept_name_index on tb(dept,name);
?
- 方式二: alter? table? 表名? 索引類型? 索引名(字段)
單值索引:alter table tb add index dept_index(dept);
創建唯一索引:alter table tb add unique index name_index(name);
復合索引:alter table tb add index dept_name_index(dept,name);
外此不需要commit,因為這些都是DDL語句,會自動提交
注意:
如果一個字段是primary key,則該字段默認就是主鍵索引;
主鍵索引不能是null,唯一索引可以是null。
?
刪除索引:drop index 索引名 on 表名;
drop index name_index on tb;
查詢索引:
show index from 表名;
show index from 表名\G
4.SQL性能問題
- 分析SQL的執行計劃:explain ,可以模擬SQL優化器執行SQL語句,從而讓開發人員知道自己編寫的SQL執行狀況;
- MySQL查詢優化器會干擾用戶的優化
官網SQL優化介紹(MySQL5.7):https://dev.mysql.com/doc/refman/5.7/en/optimization.html
?查詢執行計劃:explain + SQL語句
? ? ? ? ? ? ? ? ? ? ? ? ? explain select *from tb;
id:編號
select_type:表
table : 表
type :類型
possible_keys : 預測用到的索引
key :實際使用的索引
key_len : 實際使用索引的長度
ref:表之間的作用
rows:通過索引查詢到的數量
Extra:額外的信息
?
準備數據:
create table coures( cid int(3), cname varchar(10), tid int(3) ); create table teacher( tid int(3), tname varchar(20), tcid int(3) ); create table teacherCard( tcid int(3), tcdesc varchar(200) );分別插入數據:?
insert into coures values(1,'java',1); insert into coures values(2,'html',1); insert into coures values(3,'sql',2); insert into coures values(4,'web',3); insert into teacher values(1,'tz',1); insert into teacher values(2,'tw',2); insert into teacher values(3,'tl',3); insert into teacherCard values(1,'tzdesc'); insert into teacherCard values(2,'twdesc'); insert into teacherCard values(3,'tldesc');?
查詢:課程編號為2或者教師證編號為3的老師信息:
?先寫出查詢語句(三表關聯):
select t.* from teacher t , coures c, teacherCard tc where t.tid = c.tid and t.tcid = tc.tcid and (c.cid = 2 or tc.tcid = 3);加入explain,執行:
explain select t.* from teacher t , coures c, teacherCard tc where t.tid = c.tid and t.tcid = tc.tcid and (c.cid = 2 or tc.tcid = 3);?id:id值相同,從上往下順序執行,依次執行:teacher、teacherCard、coures表的查詢,t3-tc3-c4
執行命令:select * from teacher;
?執行命令:select * from teacherCard;
執行命令:select * from coures;
給teacher表增加一些數據:insert into teacher values(4,'ta',4);
依次再增加數據:
insert into teacher values(5,'tb',5);
insert into teacher values(6,'tc',6);
commit;
再次執行:
explain select t.* from teacher t , coures c, teacherCard tc where t.tid = c.tid and t.tcid = tc.tcid and (c.cid = 2 or tc.tcid = 3);查詢效果得到:?
?
查詢順序為:tc3--c4--t6
表的執行順序,因數量的個數改變而改變的原因:笛卡爾積
所以查詢順序變化的原因是,中間數據量越小越好。
結論:數據小的表,優先查詢
結論驗證,執行:
delete from coures where cid >2 ; commit;再次執行:
explain select t.* from teacher t , coures c, teacherCard tc where t.tid = c.tid and t.tcid = tc.tcid and (c.cid = 2 or tc.tcid = 3);?
id值不同:則id值越大越優先查詢。(本質:在嵌套子查詢時,先查內層,再查外層)
例子,查詢教授SQL課程的老師的描述(desc)
?執行查詢語句:
explain select tc.tcdesc from teacherCard tc, coures c ,?teacher t where c.tid = t.tid and t.tcid = tc.tcid and c.cname = 'sql' ;?
?將以上多表查詢,轉為子查詢形式:
explain select tc.tcdesc from teacherCard tc where tc.tcid = (select t.tcid from teacher t where t.tid = ( select c.tid from coures c where c.cname = 'sql'));?
?
子查詢+多表:
explain select t.tname,tc.tcdesc from teacher t, teacherCard tc where t.tcid = tc.tcid and t.tid = (select c.tid from coures c where cname = 'sql');?
id值有相同,又有不同:id值越大越優先,id值相同,從上往下順序執行。
?
select_type:
PRIMARY:包含子查詢SQL中的主查詢(最外層)
SUBQUERY:包含子查詢SQL中的子查詢(非最外層)
simple:簡單查詢(不包含子查詢、union)
derived:衍生查詢(使用到了臨時表),觸發條件為:
- 在from子查詢中只有一張表;
- explain select cr.cname?from (select *from coures where tid in (1,2)) cr;
- ?
- 在from子查詢中,如果有table1 union table2,則table1 就是 derived,table2就是union
- explain select cr.cname from (select *from coures where tid = 1 union select *from coures where tid = 2) cr;
?
?UNION RESULT :告知開發人員,哪些表之間存在union查詢。
未完待續……
總結
以上是生活随笔為你收集整理的CentOS7环境下MySQL踩坑记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 气象数据grib/grib2的处理方法汇
- 下一篇: 【限流01】限流算法理论篇