本篇文章主要介紹的關於本人在使用MySql記錄筆記的一些使用方法和經驗,溫馨提示,本文有點長,約1.5w字,幾十張圖片,建議收藏檢視。
下載地址:https://dev.mysql.com/downloads/
在安裝MySql之前,檢視是否以及安裝過MySql,如果已經安裝,但是不符合要求的話就解除安裝。
如果是windows安裝的話,下載windows的安裝包,一路next下去,設定好賬號和密碼就行了。
1,查詢以前是否裝有mysql
先輸入:
rpm -qa|grep -i mysql
檢視是否安裝了mysql
2,停止mysql服務、刪除之前安裝的mysql
輸入:
ps -ef|grep mysql
刪除命令
輸入:
rpm -e –nodeps 包名
如果提示依賴包錯誤,則使用以下命令嘗試
rpm -ev 包名 --nodeps
如果提示錯誤:error: %preun(xxxxxx) scriptlet failed, exit status 1
則用以下命令嘗試:
rpm -e --noscripts 包名
3、查詢並刪除mysql目錄
查詢結果如下:
find / -name mysql
刪除對應的mysql目錄
具體的步驟如圖:查詢目錄並刪除
注意:解除安裝後/etc/my.cnf不會刪除,需要進行手工刪除
4、再次查詢機器是否安裝mysql
rpm -qa|grep -i mysql
Mysql有兩種安裝模式,可自行選擇。
首先檢視mysql 是否已經安裝
輸入:
rpm -qa | grep mysql
如果已經安裝,想刪除的話
輸入:
普通刪除命令:
rpm -e mysql
強力刪除命令:
rpm -e --nodeps mysql
依賴檔案也會刪除
安裝mysql
輸入:
yum list mysql-server
如果沒有,則通過wget命令下載該包
輸入:
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
下載成功之後,再輸入命令安裝
yum install mysql-server
在安裝過程中遇到選擇輸入y就行了
安裝成功後,輸入 service mysqld start 啟動服務
輸入:
mysqladmin -u root -p password '123456'
來設定密碼
輸入之後直接回車(預設是沒有密碼的)
然後再輸入
mysql -u root -p
通過授權法更改遠端連線許可權
輸入: grant all privileges on . to 'root'@'%' identified by '123456';
注:第一個’root’是使用者名稱,第二個’%’是所有的ip都可以遠端存取,第三個’123456’表示 使用者密碼 如果不常用 就關閉掉
輸入:flush privileges; //重新整理
在防火牆關閉之後,使用SQLYog之類的工具測試是否能正確連線
將下載好的mysql安裝包上傳到linux伺服器
解壓mysql解壓包,並移動到/usr/local目錄下,重新命名為mysql。
命令:
tar -xvf mysql-5.6.21-linux-glibc2.5-x86_64.tar.gz
mv mysql-5.6.21-linux-glibc2.5-x86_64 /usr/local
cd /usr/local
mv mysql-5.6.21-linux-glibc2.5-x86_64 mysql
注: mysql預設的路徑是就是/usr/local/mysql ,如果安裝的地方更改,需要更改相應的組態檔。
切換到mysql的目錄 /usr/local/mysql
輸入:
./scripts/mysql_install_db --user=mysql
成功安裝mysql之後,輸入
service mysql start 或 /etc/init.d/mysql start
檢視是否啟動成功
輸入:
ps -ef|grep mysql
切換到 /usr/local/mysql/bin 目錄下
設定密碼
mysqladmin -u root password '123456'入mysql
輸入:
mysql -u root -p
設定遠端連線許可權
輸入:
grant all privileges on *.* to 'root'@'%' identified by '123456';
然後輸入:
flush privileges;
說明: 第一個’root’是使用者名稱,第二個’%’是所有的ip都可以遠端存取,第三個’123456’表示使用者密碼 如果不常用就關閉掉。
使用本地連線工具連線測試
SHOW FULL PROCESSLIST;
show variables like "%innodb%";
show variables like 'event_scheduler';
是否鎖表:
SHOW OPEN TABLES WHERE In_use > 0;
SHOW INNODB STATUS/G;
SHOW VARIABLES LIKE '%datadir%'
show variables like '%timeout%';
show variables like 'datadir';
mysql的紀錄檔分類
錯誤紀錄檔: -log-err
查詢紀錄檔: -log
慢查詢紀錄檔: -log-slow-queries
更新紀錄檔: -log-update
二進位制紀錄檔: -log-bin
輸入:
SHOW VARIABLES LIKE 'log_bin'
開啟錯誤紀錄檔:
在my.cnf 或my.ini 中 新增 log-error=/home/mysql/logs/log-error.txt
開啟查詢紀錄檔:
在my.cnf 或my.ini 中 新增 log=/home/mysql/logs/mysql_log.txt
SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';
chown -R mysql:mysql ./
USE performance_schema;
SELECT VARIABLE_VALUE INTO @a FROM global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';
SELECT VARIABLE_VALUE INTO @b FROM global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
SELECT @a/@b;
要合理的設定 innodb_io_capacity 的值,平時要多關注髒頁比例,不讓其接近 75%.
可以通過 innodb_flush_neighbors 來控制該行為,值為 1 開啟上述機制,為 0 則關閉。
對於機械硬碟來說,是可以減少很多隨機 IO ,因為機械硬碟 IOPS 一般就幾百,減少隨機 IO 就意味著效能提升。
但如果用 SSD 這類 IOPS 較高的裝置,IOPS 往往不是瓶頸,關閉就好,減少 SQL 語句的響應時間。
在 8.0 中,已經預設是 0 了.
SHOW VARIABLES LIKE 'slow_query%';
SET GLOBAL slow_query_log=ON;
set global long_query_time=1;
永久設定
[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1
long_query_time表示查詢超過多少秒就記錄
開啟會降低效能
檢視紀錄檔設定
SHOW VARIABLES LIKE '%general_log%';
查詢檔案輸出格式
SHOW VARIABLES LIKE 'log_output';
開啟MySQL查詢紀錄檔
SET GLOBAL general_log = ON;
關閉MySQL查詢紀錄檔
SET GLOBAL general_log = OFF;
設定紀錄檔輸出方式為表
SET GLOBAL log_output='table';
查詢紀錄檔資訊
select * from mysql.general_log;
按使用者端 IP 分組,看哪個使用者端的連結數最多
SELECT client_ip,COUNT(client_ip) AS client_num FROM (SELECT
SUBSTRING_INDEX(HOST,':' ,1) AS client_ip FROM PROCESSLIST ) AS
connect_info GROUP BY client_ip ORDER BY client_num DESC;
檢視正在執行的執行緒,並按 Time 倒排序,看看有沒有執行時間特別長的執行緒
SELECT * FROM information_schema.processlist WHERE Command != 'Sleep'
ORDER BY TIME DESC;
找出所有執行時間超過 5 分鐘的執行緒,拼湊出 kill 語句,方便後面查殺
SELECT CONCAT('kill ', id, ';') FROM information_schema.processlist
WHERE Command != 'Sleep' AND TIME > 300 ORDER BY TIME DESC;
批次kill的語句
select concat('KILL ',a.trx_mysql_thread_id ,';') from INFORMATION_SCHEMA.INNODB_LOCKS b,INFORMATION_SCHEMA.innodb_trx a where b.lock_trx_id=a.trx_id into outfile '/tmp/kill.txt';
MySQL支援很多資料型別,選擇合適的資料型別儲存資料對效能有很大的影響。通常來說,可以遵循以下一些指導原則:
1.越小的資料型別通常更好:
越小的資料型別通常在磁碟、記憶體和CPU快取中都需要更少的空間,處理起來更快。
2.簡單的資料型別更好:
整型資料比起字元,處理開銷更小,因為字串的比較更復雜。在MySQL中,應該用內建的日期和時間資料型別,而不是用字串來儲存時間;以及用整型資料型別儲存IP地址。
3.儘量避免NULL:
應該指定列為NOT NULL,除非你想儲存NULL。在MySQL中,含有空值的列很難進行查詢優化,因為它們使得索引、索引的統計資訊以及比較運算更加複雜。你應該用0、一個特殊的值或者一個空串代替空值。
4.一個表的索引最好不要超過6個:
索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引
選擇合適的識別符號是非常重要的。選擇時不僅應該考慮儲存型別,而且應該考慮MySQL是怎樣進行運算和比較的。一旦選定資料型別,應該保證所有相關的表都使用相同的資料型別。
Mysql常見索引有:主鍵索引、唯一索引、普通索引、全文索引、組合索引
PRIMARY KEY(主鍵索引) ALTER TABLE table_name
ADD PRIMARY KEY ( col
)
UNIQUE(唯一索引) ALTER TABLE table_name
ADD UNIQUE (col
)
INDEX(普通索引) ALTER TABLE table_name
ADD INDEX index_name (col
)
FULLTEXT(全文索引) ALTER TABLE table_name
ADD FULLTEXT ( col
)
組合索引 ALTER TABLE table_name
ADD INDEX index_name (col1
, col2
, col3
)
Mysql各種索引區別:
普通索引:最基本的索引,沒有任何限制
唯一索引:與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。
主鍵索引:它 是一種特殊的唯一索引,不允許有空值。
全文索引:僅可用於 MyISAM 表,針對較大的資料,生成全文索引很耗時好空間。
聯合索引:為了更多的提高mysql效率可建立組合索引,遵循」最左字首「原則。建立複合索引時應該將最常用(頻率)作限制條件的列放在最左邊,依次遞減。
聯合索引的好處:覆蓋索引,這一點是最重要的,眾所周知非主鍵索引會先查到主鍵索引的值再從主鍵索引上拿到想要的值。但是覆蓋索引可以直接在非主鍵索引上拿到相應的值,減少一次查詢。
複合索引和普通索引都是用一棵B+樹表示的。
如果是單列,就按這列key資料進行排序。
如果是多列,就按多列資料排序,
例如有(1,1)(1,4)(2,2)(1,3) (2,1)(1,2)(2,3) (2,4)
那在索引中的葉子節點的資料順序就是(1,1)(1,2)(1,3) (1,4)(2,1)(2,2)(2,3) (2,4)
這也是為什麼查詢複合索引的字首是可以用到索引的原因
Hash僅支援=、>、>=、<、<=、between。BTree可以支援like模糊查詢
索引是幫助mysql獲取資料的資料結構。最常見的索引是Btree索引和Hash索引。
不同的引擎對於索引有不同的支援:Innodb和MyISAM預設的索引是Btree索引;而Mermory預設的索引是Hash索引。
我們在mysql中常用兩種索引演演算法BTree和Hash,兩種演演算法檢索方式不一樣,對查詢的作用也不一樣。
一、BTree
BTree索引是最常用的mysql資料庫索引演演算法,因為它不僅可以被用在=,>,>=,<,<=和between這些比較操作符上,而且還可以用於like操作符,只要它的查詢條件是一個不以萬用字元開頭的常數,例如:
select * from user where name like ‘jack%’;
select * from user where name like ‘jac%k%’;
如果一萬用字元開頭,或者沒有使用常數,則不會使用索引,例如:
select * from user where name like ‘%jack’;
select * from user where name like simply_name;
二、Hash
Hash索引只能用於對等比較,例如=,<=>(相當於=)操作符。由於是一次定位資料,不像BTree索引需要從根節點到枝節點,最後才能存取到頁節點這樣多次IO存取,所以檢索效率遠高於BTree索引。
但為什麼我們使用BTree比使用Hash多呢?主要Hash本身由於其特殊性,也帶來了很多限制和弊端:
1.Hash索引僅僅能滿足「=」,「IN」,「<=>」查詢,不能使用範圍查詢。
2.聯合索引中,Hash索引不能利用部分索引鍵查詢。
對於聯合索引中的多個列,Hash是要麼全部使用,要麼全部不使用,並不支援BTree支援的聯合索引的最優字首,也就是聯合索引的前面一個或幾個索引鍵進行查詢時,Hash索引無法被利用。
3.Hash索引無法避免資料的排序操作
由於Hash索引中存放的是經過Hash計算之後的Hash值,而且Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣,所以資料庫無法利用索引的資料來避免任何排序運算。
4.Hash索引任何時候都不能避免表掃描
Hash索引是將索引鍵通過Hash運算之後,將Hash運算結果的Hash值和所對應的行指標資訊存放於一個Hash表中,由於不同索引鍵存在相同Hash值,所以即使滿足某個Hash鍵值的資料的記錄條數,也無法從Hash索引中直接完成查詢,還是要通過存取表中的實際資料進行比較,並得到相應的結果。
5.Hash索引遇到大量Hash值相等的情況後效能並不一定會比BTree高
對於選擇性比較低的索引鍵,如果建立Hash索引,那麼將會存在大量記錄指標資訊存於同一個Hash值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表資料存取,而造成整體效能底下。
資料量太少:
如果表中的行數很少,MySQL可能會選擇全表掃描而不是使用索引。
索引列被函數處理:
如果查詢中對索引列進行了函數處理,MySQL就無法使用該索引進行優化,例如:
SELECT * FROM table WHERE YEAR(date_column) = 2021;
將無法使用date_column上的索引進行優化。
SELECT * FROM table WHERE int_column = '1';
將無法使用int_column上的索引進行優化。
索引列被模糊查詢:
如果查詢中對索引列進行了模糊查詢(如使用LIKE, 非左匹配),MySQL也無法使用該索引進行優化。
多列索引未使用字首:
如果使用了多列索引,並且查詢中只使用了其中的一部分列,但是沒有使用字首,MySQL也無法使用該索引進行優化。
索引列存在NULL值:
如果索引列存在NULL值,MySQL可能無法使用該索引進行優化。
查詢條件中包含OR、NOT、IN以及子查詢的情況。
使用聯合索引但是查詢條件順序不正確。
left join 字元集不一致
這種情況並非常見
可以通過以下語句檢視:
SHOW FULL COLUMNS FROM table1;
SHOW FULL COLUMNS FROM table2;
通過關鍵字 EXPLAIN 在查詢語句前面加上可以檢視索引走向
從上到下,效能從差到好
優化建議:
JOIN 後的的條件必須是索引,最好是唯一索引,否則資料一旦很多會直接卡死
一般禁止使用UNIION ON,除非UNION ON 前後的記錄數很少
禁止使用OR
查總數使用COUNT(*)就可以,不需要COUNT(ID),MYSQL會自動優化
資料庫欄位設定 NOT NULL,欄位型別 INT > VARCHAR 越小越好
禁止SELECT * ,需要確定到使用的欄位
一般情況不在SQL中進行數值計算
1.如果未設定主鍵,也未設定索引,可以對整型的欄位新增索引
2.通過一箇中間表來記錄資料庫內各表記錄總數,然後通過觸發器進行監聽該表,實時更新總條數.
觸發器:
CREATE
TRIGGER 資料庫名
.觸發器名
BEFORE/AFTER INSERT/UPDATE/DELETE
ON 資料庫名
.<Table Name>
FOR EACH ROW
BEGIN
事件發生後執行的程式碼
END
建立範例:
當test_count表新增了資料,就對MT_COUNT的總數進行更新。
DELIMITER $$
CREATE
TRIGGER `ROWS_COUNT` BEFORE INSERT
ON `test_count`
FOR EACH ROW BEGIN
UPDATE MT_COUNT SET rowcount=rowcount+1 WHERE tablename = 'test_count';
END$$
DELIMITER ;
3.分頁查詢只第一次查詢總數,或者分頁查詢和總數查詢分開。
innodb_buffer_pool_size
如果用Innodb,那麼這是一個重要變數。相對於MyISAM來說,Innodb對於buffer
size更敏感。MySIAM可能對於巨量資料量使用預設的key_buffer_size也還好,但Innodb在巨量資料量時用預設值就感覺在爬了。
Innodb的緩衝池會快取資料和索引,所以不需要給系統的快取留空間,如果只用Innodb,可以把這個值設為記憶體的70%-80%。和
key_buffer相同,如果資料量比較小也不怎麼增加,那麼不要把這個值設太高也可以提高記憶體的使用率。
innodb_additional_pool_size
這個的效果不是很明顯,至少是當作業系統能合理分配記憶體時。但你可能仍需要設成20M或更多一點以看Innodb會分配多少記憶體做其他用途。
innodb_log_file_size
對於寫很多尤其是巨量資料量時非常重要。要注意,大的檔案提供更高的效能,但資料庫恢復時會用更多的時間。一般用64M-512M,具體取決於伺服器的空間。
innodb_log_buffer_size
預設值對於多數中等寫操作和事務短的運用都是可以的。如
果經常做更新或者使用了很多blob資料,應該增大這個值。但太大了也是浪費記憶體,因為1秒鐘總會
flush(這個詞的中文怎麼說呢?)一次,所以不需要設到超過1秒的需求。8M-16M一般應該夠了。小的運用可以設更小一點。
innodb_flush_log_at_trx_commit (這個很管用)
抱怨Innodb比MyISAM慢
100倍?那麼你大概是忘了調整這個值。預設值1的意思是每一次事務提交或事務外的指令都需要把紀錄檔寫入(flush)硬碟,這是很費時的。特別是使用電
池供電快取(Battery backed up
cache)時。設成2對於很多運用,特別是從MyISAM錶轉過來的是可以的,它的意思是不寫入硬碟而是寫入系統快取。紀錄檔仍然會每秒flush到硬
盤,所以你一般不會丟失超過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL掛了也可能會丟失事務的資料。而值2只會在整個作業系統
掛了時才可能丟資料。
原因:沒有該使用者。
解決辦法:建立該使用者!
例如:
新增使用者:
groupadd -g 315 mysql
使用者加入mysql:
useradd -u 315 -g mysql -d /usr/local/mysql -M mysql
再次輸入
./scripts/mysql_install_db --user=mysql
成功!
問題原因: 是因為/etc/init.d/ 不存在 mysql 這個命令,所以無法識別。
解決辦法:
1.首先查詢mysql.server檔案在哪
輸入:
find / -name mysql.server
2.將mysql.server 複製到/etc/init.d/目錄下,並重新命名為mysql或mysqld
輸入:
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
3.測試是否可以使用該命令
輸入:
service mysql status
或
service mysqld status
原因:mysql伺服器的儲存空間不夠了,清空不用的資料就可以使用了。
1.資料庫中設定的字元長度不夠
找到對應的欄位,將字元長度加長一些。
2.編碼導致的原因,一般是由於輸入了中文,才會出現類似的錯誤
統一設定為UTF-8
登入出現此異常
原因: 沒有找到該檔案,可以在/etc/my.cnf 檔案中確認該檔案的位置,若確定,這檢視此檔案的許可權,若許可權也ok,則新增 軟鏈,
例如:
ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
若還不行,則通過 mysql -uroot -p -S /var/run/mysqld/mysqld.sock 直接登入,不輸入密碼 。登入成功之後,在通過新增軟鏈重新啟動。
原因:這是由於系統預設會查詢/usr/bin下的命令,如果這個命令不在這個目錄下,當然會找不到命令,我們需要做的就是對映一個連結到/usr/bin目錄下,相當於建立一個連結檔案。
首先得知道mysql命令或mysqladmin命令的完整路徑,比如mysql的路徑是:/usr/local/mysql/bin/mysql,我們則可以這樣執行命令:
ln -s /usr/local/mysql/bin/mysql /usr/bin
以下是補充:
linux下,在mysql正常執行的情況下,輸入mysql提示:
mysql command not found
遇上-bash: mysql: command not found的情況彆著急,這個是因為/usr/local/bin目錄下缺失mysql導致,只需要一下方法建立軟連結,即可以解決:
把mysql安裝目錄,比如MYSQLPATH/bin/mysql,對映到/usr/local/bin目錄下:
cd /usr/local/bin
ln -fs /MYSQLPATH/bin/mysql mysql
還有其它常用命令mysqladmin、mysqldump等不可用時候都可按用此方法解決。
注:其中MYSQLPATH是mysql的實際安裝路徑。
報這個錯誤的原因是因為你的mysql資料庫已經進行初始化了,所以不能用這種方式再進行初始化使用者了,因為mysql在初始化的時候會自動建立一個root使用者的。更改/etc/cnf 的設定就行。
錯誤資訊詳細描述:
root@MyServer:~# service mysql start
Starting MySQL
..The server quit without updating PID file (/usr/local/mysql/var/MyServer.pid). ... failed!
錯誤解決排查思路:
1.可能是/usr/local/mysql/data/rekfan.pid檔案沒有寫的許可權
解決方法 :給予許可權,執行 「chown -R mysql:mysql /var/data」 「chmod -R 755 /usr/local/mysql/data」 然後重新啟動mysqld!
2.可能程序裡已經存在mysql程序
解決方法:用命令「ps -ef|grep mysqld」檢視是否有mysqld程序,如果有使用「kill -9 程序號」殺死,然後重新啟動mysqld!
3.可能是第二次在機器上安裝mysql,有殘餘資料影響了服務的啟動。
解決方法:去mysql的資料目錄/data看看,如果存在mysql-bin.index,就趕快把它刪除掉吧,它就是罪魁禍首了。
4.mysql在啟動時沒有指定組態檔時會使用/etc/my.cnf組態檔,請開啟這個檔案檢視在[mysqld]節下有沒有指定資料目錄(datadir)。
解決方法:請在[mysqld]下設定這一行:datadir = /usr/local/mysql/data
5.skip-federated欄位問題
解決方法:檢查一下/etc/my.cnf檔案中有沒有沒被註釋掉的skip-federated欄位,如果有就立即註釋掉吧。
6.錯誤紀錄檔目錄不存在
解決方法:使用「chown」 「chmod」命令賦予mysql所有者及許可權
7.selinux惹的禍,如果是centos系統,預設會開啟selinux
解決方法:關閉它,開啟/etc/selinux/config,把SELINUX=enforcing改為SELINUX=disabled後存檔退出重啟機器試試。
systemctl list-unit-files --type=service | grep mysql
service mysqld.service start
新增雙引號
問題: 插入SQ語句出現 Incorrect string value: '\xF0\xA1\x8B\xBE\xE5\xA2...' for column 'name',這種錯誤,資料庫編碼設定已經是utf-8 ,插入其他的非特殊字元的語句正確。
解決辦法 : mysql 版本5.5.3以後,有了一個utf8mb4編碼,是utf8的超集,也相容unicode 。所以將編碼格式改為這個就可以了。
在my.cnf或my.ini中新增:
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4
參考:
http://blog.csdn.net/zq199692288/article/details/78863737
https://blog.csdn.net/hjf161105/article/details/78850658
https://blog.csdn.net/everda/article/details/77476716
http://blog.itpub.net/29654823/viewspace-2150471
關於sql相關的文章:
https://www.cnblogs.com/xuwujing/category/1081197.html
非常好聽的音樂~
原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力!
版權宣告:
作者:虛無境
部落格園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm
個人部落格出處:https://xuwujing.github.io/