MySQL優化技巧總結


MySQL優化的幾個大方向

① 硬件優化
② 對MySQL配置參數進行優化(my.cnf)此優化需要進行壓力測試來進行參數調整
③ SQL語句方面的優化
④ 表方面的優化
 

硬件優化

cpu,內存,硬盤等硬件的優化

 

MySQL參數優化

設置最大連接數
set globle max_connections = 5000;

long_query_time = 2 超過兩秒的查詢記錄下來

log_slow_queries = /data/mysql/slowlog.log

query_cache_size = 64M

 

SQL語句方面的優化

●修改mysql的慢查詢

show variables like ‘long_query_time’ ; //可以顯示當前慢查詢時間

set long_query_time=1 ;//可以修改慢查詢時間

詳情:https://www.cnblogs.com/luyucheng/p/6265594.html

●使用查詢緩存優化查詢

大多數的MySQL服務器都開啟了查詢緩存。這是提高性能最有效的方法之一,而且這是被MySQL引擎處理的。當有很多相同的查詢被執行了多次的時候,這些查詢結果會被放入一個緩存中,這樣后續的相同查詢就不用操作而直接訪問緩存結果了。
這里最主要的問題是,對於我們程序員來說,這個事情是很容易被忽略的。因為我們某些查詢語句會讓MySQL不使用緩存,示例如下:
1:SELECT username FROM user WHERE    signup_date >= CURDATE()
2:SELECT username FROM user WHERE    signup_date >= '2014-06-24‘
上面兩條SQL語句的差別就是 CURDATE() ,MySQL的查詢緩存對這個函數不起作用。所以,像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數都不會開啟查詢緩存,因為這些函數的返回是會不定的易變的。所以,你所需要的就是用一個變量來代替MySQL的函數,從而開啟緩存。

●使用EXPLAIN關鍵字檢測查詢

●當只要一行數據時使用LIMIT 1

●只去自己需要的column,避免使用SELECT *

●添加索引(主鍵索引/唯一索引/全文索引/普通索引)

1.添加

1.1主鍵索引添加

當一張表,把某個列設為主鍵的時候,則該列就是主鍵索引

1 create table aaa 2 (id int unsigned primary key auto_increment , 3 name varchar(32) not null defaul '');

這是id 列就是主鍵索引

如果你創建表時,沒有指定主鍵索引,也可以在創建表后,在添加, 指令:

1 alter table 表名 add primary key (列名);

舉例:

1 create table bbb (id int , name varchar(32) not null default ‘’); 2 alter table bbb add primary key (id);

 

1.2普通索引

一般來說,普通索引的創建,是先創建表,然后在創建普通索引

比如:

1 create table ccc( 2 id int unsigned, 3 name varchar(32) 4 ) 
1 create index 索引名 on 表 (列1,列名2);

 

1.3創建全文索引

全文索引,主要是針對對文件,文本的檢索, 比如文章(5.5版本以后,innodb 支持全文索引)

創建 :

復制代碼
 1 CREATE TABLE articles (  2  3 id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,  4  5 title VARCHAR(200),  6  7 body TEXT,  8  9  FULLTEXT (title,body) 10 11 )engine=myisam charset utf8;
復制代碼

 

復制代碼
 1 INSERT INTO articles (title,body) VALUES  2  3 ('MySQL Tutorial','DBMS stands for DataBase ...'),  4  5 ('How To Use MySQL Well','After you went through a ...'),  6  7 ('Optimizing MySQL','In this tutorial we will show ...'),  8  9 ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), 10 11 ('MySQL vs. YourSQL','In the following database comparison ...'), 12 13 ('MySQL Security','When configured properly, MySQL ...'); 
復制代碼

如何使用全文索引:

錯誤用法:

select * from articles where body like ‘%mysql%’; 【不會使用到全文索引】

證明:

1 explain  select * from articles where body like ‘%mysql%’ 

正確的用法是:

1 select * from articles where match(title,body) against(‘database’);  

測速匹配度

1 mysql> select id, match(title,body) against('dbms') from articles;

 

常用的詞語,匹配度反而很低或者為0(假如常用的單詞都要匹配的話,每條數據基本上都會匹配上,那搜索效率就很慢了) 如:

 

MySQL 使用一個非常簡單的剖析器來將文本分隔成詞。一個“詞”是由文字、數據、“'” 和 “_” 組成的任何字符序列。任何在 stopword 列表上出現的,或太短的(3 個字符或更少的)的 “word” 將被忽略。

在集和查詢中的每個合適的詞根據其在集與查詢中的重要性衡量。這樣,一個出現在多個文檔中的詞將有較低的權重(可能甚至有一個零權重),因為在這個特定的集中,它有較低的語義值。否則,如果詞是較少的,它將得到一個較高的權重。然后,詞的權重將被結合用於計算記錄行的相似性。

這樣一個技術工作可很好地工作與大的集(實際上,它會小心地與之諧調)。 對於非常小的表,詞分類不足以充份地反應它們的語義值,有時這個模式可能產生奇怪的結果。

mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL');
Empty set (0.00 sec)

在上面的例子中,搜索詞 MySQL 卻沒有得到任何結果,因為這個詞在超過一半的記錄行中出現。同樣的,它被有效地處理為一個 stopword (即,一個零語義值的詞)。這是最理想的行為 -- 一個自然語言的查詢不應該從一個 1GB 的表中返回每個次行(second row)。

匹配表中一半記錄行的詞很少可能找到相關文檔。實際上,它可能會發現許多不相關的文檔。我們都知道,當我們在互聯網上通過搜索引擎試圖搜索某些東西時,這會經常發生。因為這個原因,在這個特殊的數據集中,這樣的行被設置一個低的語義值。

 詳情:http://blog.sina.com.cn/s/blog_63426ff901014l2d.html

全文說明:

  1. 在mysql中fulltext 索引只針對 myisam生效(5.5版本以后,innodb 支持全文索引)
  2. mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文
  3. 使用方法是 match(字段名..) against(‘關鍵字’)
  4. 全文索引一個 叫 停止詞,  因為在一個文本中,創建索引是一個無窮大的數,因此,對一些常用詞和字符,就不會創建,這些詞,稱為停止詞.

1.4唯一索引

①當表的某列被指定為unique約束時,這列就是一個唯一索引

1 create table ddd(id int primary key auto_increment , name varchar(32) unique);

 

這時, name 列就是一個唯一索引.

unique字段可以為NULL,並可以有多NULL, 但是如果是具體內容,則不能重復.

主鍵字段,不能為NULL,也不能重復.

②在創建表后,再去創建唯一索引

1 create table eee(id int primary key auto_increment, name varchar(32)); 2 create unique index 索引名 on 表名 (列表..);

 

 

2.查詢索引

desc 表名 【該方法的缺點是: 不能夠顯示索引名.】

show index(es) from 表名

show keys from 表名

 

3.刪除

alter table 表名 drop index 索引名;

 

如果刪除主鍵索引。

alter table 表名 drop primary key

 

4.修改

先刪除,再重新創建.

 

二叉樹算法的索引實現原理:

 

索引的代價:

  1. 占用磁盤空間
  2. 對dml操作有影響,變慢

在哪些列上適合添加索引?

總結: 滿足以下條件的字段,才應該創建索引.

a: 肯定在where條經常使用 b: 該字段的內容不是唯一的幾個值(sex) c: 字段內容不是頻繁變化.

 

使用索引的注意事項

把dept表中,我增加幾個部門:

1 alter table dept add index my_ind (dname,loc); // dname 左邊的列,loc就是右邊的列

說明,如果我們的表中有復合索引(索引作用在多列上), 此時我們注意:

1,  對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。 explain select * from dept where loc='aaa'\G   就不會使用到索引

2,對於使用like的查詢,查詢如果是  ‘%aaa’ 不會使用到索引,‘aaa%’ 會使用到索引。

比如: explain select * from dept where dname like '%aaa'\G

不能使用索引,即,在like查詢時,關鍵的 ‘關鍵字’ , 最前面,不能使用 % 或者 _這樣的字符., 如果一定要前面有變化的值,則考慮使用 全文索引->sphinx.

3.如果條件中有or,即使其中有條件帶索引也不會使用(select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45)。換言之,就是要求使用的所有字段,都必須建立索引, 我們建議大家盡量避免使用or 關鍵字

4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字符串必須’’), 也就是,如果列是字符串類型,就一定要用 ‘’ 把他包括起來.

5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

 

表方面的優化

●永遠為每張表設置一個ID主鍵

●越小的列會越快

對於大多數的數據庫引擎來說,硬盤操作可能是最重大的瓶頸。所以,把我們的數據變得緊湊會對這種情況非常有幫助,因為這減少了對硬盤的訪問。 參看 MySQL 的文檔 Storage Requirements 查看所有的數據類型。 如果一個表只會有幾列罷了(比如說字典表,配置表),那么,我們就沒有理由使用 INT 來做主鍵,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 會更經濟一些。如果我們不需要記錄時間,使用 DATE 要比 DATETIME 好得多。 
“性別”,“國家”,“民族”,“狀態”或“部門”等字段,我們知道這些字段的取值是有限而且固定的,那么,我們應該使用 ENUM 而不是 VARCHAR。

●建表符合三范式

●選擇合適的存儲引擎

myisam 存儲: 如果表對事務要求不高,同時是以查詢和添加為主的,我們考慮使用myisam存儲引擎. ,比如 bbs 中的 發帖表,回復表.

INNODB 存儲: 對事務要求高,保存的數據都是重要數據,我們建議使用INNODB,比如訂單表,賬號表.

MyISAM 和 INNODB的區別

1. 事務安全

2. 查詢和添加速度

3. 支持全文索引(5.5版本以后,innodb 支持全文索引)

4. 鎖機制

5. 外鍵 MyISAM 不支持外鍵, INNODB支持外鍵

 

 

 

●mysql讀寫分離

●對表進行水平分割

當一張越來越大時候,即使添加索引還慢的話,我們可以使用分表(即存在不同的表里)

●對表進行垂直分割

如果一張表某個字段,信息量大,但是我們很少查詢,則可以考慮把這些字段,單獨的放入到一張表中,這種方式稱為垂直分割

● 如果你的數據庫的存儲引擎是myisam,請一定記住要定時進行碎片整理

optimize table 表名;


免責聲明!

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



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