mysql性能優化


mysql數據庫的優化技術

1、mysql優化是一個綜合性的技術,主要包括

 1. 表的設計合理化(符合3NF)
 2. 添加適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引]
 3. 分表技術(水平分割、垂直分割)
 4. 讀寫[寫: update/delete/add]分離
 5. 存儲過程 [模塊化編程,可以提高速度]
 6. 對mysql配置優化 [配置最大並發數my.ini, 調整緩存大小 ]
 7. mysql服務器硬件升級
 8. 定時的去清除不需要的數據,定時進行碎片整理(MyISAM)

2、要保證數據庫的效率,要做好以下四個方面的工作

 1. 數據庫設計
 2. sql語句優化
 3. 數據庫參數配置
 4. 恰當的硬件資源和操作系統

 此外,使用適當的存儲過程,也能提升性能。
 這個順序也表現了這四個工作對性能影響的大小

數據庫表設計

1、通俗地理解三個范式

 第一范式: 1NF是對屬性的原子性約束,要求屬性(列)具有原子性,不可再分解;(只要是關系型數據庫都滿足1NF)

 第二范式: 2NF是對記錄的惟一性約束,要求記錄有惟一標識,即實體的惟一性;

 第三范式: 3NF是對字段冗余性的約束,它要求字段沒有冗余。 沒有冗余的數據庫設計可以做到。

2、第一范式(1NF)

 1. 即表的列的具有原子性,不可再分解,即列的信息,不能分解, 只要數據庫是關系型數據庫(mysql/oracle/db2/informix/sysbase/sql server),就自動的滿足1NF。
 2. 數據庫表的每一列都是不可分割的原子數據項,而不能是集合,數組,記錄等非原子數據項。
 3. 如果實體中的某個屬性有多個值時,必須拆分為不同的屬性 。通俗理解即一個字段只存儲一項信息。

3、第二范式(2NF)

 1、要求數據庫表中的每個實例或行必須可以被惟一地區分。為實現區分通常需要我們設計一個主鍵來實現(這里的主鍵不包含業務邏輯)。

4、第三范式(3NF)

 1、要求一個數據庫表中不包含已在其它表中已包含的非主鍵字段。
 2、如果能夠被推導出來,就不應該單獨的設計一個字段來存放(能盡量外鍵join就用外鍵join)。
 3、很多時候,我們為了滿足第三范式往往會把一張表分成多張表。

SQL優化

1、為查詢緩存優化你的查詢

 1、大多數的MySQL服務器都開啟了查詢緩存。這是提高性最有效的方法之一,而且這是被MySQL的數據庫引擎處理的。
 2、當有很多相同的查詢被執行了多次的時候,這些查詢結果會被放到一個緩存中,這樣,后續的相同的查詢就不用操作表而直接訪問緩存結果了。
 3、像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數都不會開啟查詢緩存,因為這些函數的返回是會不定的易變的。

2、EXPLAIN 你的 SELECT 查詢

1、explain關鍵字作用

 1、使用 EXPLAIN 關鍵字可以讓你知道MySQL是如何處理你的SQL語句的。這可以幫你分析你的查詢語句或是表結構的性能瓶頸。
 2、EXPLAIN 的查詢結果還會告訴你你的索引主鍵被如何利用的,你的數據表是如何被搜索和排序的……等等,等等。

2、explain使用舉例

 Explain select * from emp where ename=“wsrcla”
 會產生如下信息:
  select_type: 表示查詢的類型。
  table:  輸出結果集的表
  type:  表示表的連接類型
  possible_keys:   表示查詢時,可能使用的索引
  key:   表示實際使用的索引
  key_len:   索引字段的長度
  rows:   掃描出的行數(估算的行數)
  Extra:   執行情況的描述和說明

3、EXPLAIN信息詳解

  1. id   SELECT識別符。這是SELECT的查詢序列號

  2. select_type 

   PRIMARY :   子查詢中最外層查詢
   SUBQUERY :    子查詢內層第一個SELECT,結果不依賴於外部查詢
   DEPENDENT SUBQUERY:   子查詢內層第一個SELECT,依賴於外部查詢
   UNION :   UNION語句中第二個SELECT開始后面所有SELECT,
   SIMPLE:  簡單的 select 查詢,不使用 union 及子查詢
   UNION :  UNION 中的第二個或隨后的 select 查詢,不依賴於外部查詢的結果集

  3. Table : 顯示這一步所訪問數據庫中表名稱

  4. Type : 對表訪問方式

   ALL:  SELECT * FROM emp \G 完整的表掃描 通常不好
   SELECT * FROM (SELECT * FROM emp WHERE empno = 1) a ;
   system:  表僅有一行(=系統表)。這是const聯接類型的一個特
   const:  表最多有一個匹配行

  5. Possible_keys : 該查詢可以利用的索引,如果沒有任何索引顯示  null

  6. Key : Mysql 從 Possible_keys 所選擇使用索引

  7. Rows :  估算出結果集行數

  8. Extra查詢細節信息
   No tables :  Query語句中使用FROM DUAL 或不含任何FROM子句
   Using filesort :  當Query中包含 ORDER BY 操作,而且無法利用索引完成排序,
   Impossible WHERE noticed after reading const tables: MYSQL Query Optimizer
   通過收集統計信息不可能存在結果
   Using temporary:  某些操作必須使用臨時表,常見 GROUP BY ; ORDER BY
   Using where:  不用讀取表中所有信息,僅通過索引就可以獲取所需數據;

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

 1、當你查詢表的有些時候,你已經知道結果只會有一條結果,但因為你可能需要去fetch游標,或是你也許會去檢查返回的記錄數。
 2、在這種情況下,加上 LIMIT 1 可以增加性能。這樣一樣,MySQL數據庫引擎會在找到一條數據后停止搜索,而不是繼續往后查少下一條符合記錄的數據。

4、建立適當的索引

1、索引為什會使查找變快

 1、btree類型的索引,就是使用的二分查找法,肯定快啊,算法復雜度是log2N,也就是說16條數據查4次,32條數據查5次,64條數據查6次....依次類推。
 2、使用索引跟沒使用索引的區別,就跟我們使用新華字典查字,一個是根據拼音或者筆畫查找,一個是從頭到尾一頁一頁翻。

2、索引的代價

 1、磁盤占用
 2、對dml(update delete insert)語句的效率影響

3、索引使用原則

 1、較頻繁的作為查詢條件字段應該創建索引
   select * from emp where empno = 1;

 2、唯一性太差的字段不適合單獨創建索引,即使頻繁作為查詢條件
   select * from emp where sex = '男'

 3、更新非常頻繁的字段不適合創建索引
   select * from emp where logincount = 1

 4、不會出現在WHERE子句中的字段不該創建索引

4、mysql四種索引的區別

 1、主鍵索引,主鍵自動的為主索引 (類型Primary)
 2、唯一索引 (UNIQUE)
 3、普通索引 (INDEX)
 4、全文索引 (FULLTEXT) [適用於MyISAM] ——》sphinx + 中文分詞 coreseek [sphinx 的中文版 ]

5、索引的使用 

 1. 建立索引

  1、create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
  2、alter table table_name ADD INDEX [index_name] (index_col_name,...)

 2.  刪除索引

  1、DROP INDEX index_name ON tbl_name;
  2、alter table table_name drop index index_name;

  注:刪除主鍵(索引)比較特別: alter table t_b drop primary key;

 3. 創建普通索引方法

  #1 查看student表中有哪些索引
    mysql> show index from student;                                   #查看student表中有哪些索引

  #2 創建最基本的的索引
    mysql> create index index_name on student(name(32));              #將student中字段name創建成索引

  #3 刪除索引的語法
    mysql> drop index index_name on student;

 4. 創建唯一索引
  注: 它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值
  #1創建索引
  mysql>  create unique index index_name on student(name(32));

6、使用或不使用索引的情況

 1. 下列幾種情況下有可能使用到索引

  1,對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。
  2,對於使用like的查詢,查詢如果是  '%aaa' 不會使用到索引, 'aaa%' 會使用到索引。

 2. 下列的表將不使用索引

  1, 如果條件中有or,即使其中有條件帶索引也不會使用。
  2, 對於多列索引,不是使用的第一部分,則不會使用索引。
  3, like查詢是以%開頭
  4, 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字符串必須'')
  5, 如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

MySQL中like模糊匹配為何低效

1、都不使用索引

      說明不使用索引的時候普通查詢與like查詢的耗時相當,like略長,這也是必然的,因為它要進行額外的算法。

                    

2、like不使用索引、普通查詢使用索引

              說明使用索引后,普通查詢的耗時基本算是秒查,非常快;而like查詢還是耗時一秒多。

                   

                  

3、like查詢起始也可以使用索引

  1)如果我們查詢的時候寫成“like 'dd_'或者like 'dd%'”,這樣是可以用到索引的,此時的查詢速度也會相對的快一點。

  2)如果查詢的時候寫成“ like '%dd'”,查詢字符串最前面就是模糊的無法使用索引

                 

數據庫優化方案

 1. 優化索引、SQL 語句、分析慢查詢

 2. 設計表的時候嚴格根據數據庫的設計范式來設計數據庫

 3. 使用緩存,把經常訪問到的數據而且不需要經常變化的數據放在緩存中,能節約磁盤IO

 4. 優化硬件;采用SSD,使用磁盤隊列技術(RAID0,RAID1,RDID5)等;

 5. 采用MySQL 內部自帶的表分區技術,把數據分層不同的文件,能夠提高磁盤的讀取效率

 6. 垂直分表;把一些不經常讀的數據放在一張表里,節約磁盤I/O

 7. 主從分離讀寫;采用主從復制把數據庫的讀操作和寫入操作分離開來

 8. 分庫分表分機器(數據量特別大),主要的的原理就是數據路由

 9. 選擇合適的表引擎,參數上的優化

 10. 進行架構級別的緩存,靜態化和分布式

 11. 不采用全文索引

數據庫怎么優化查詢效率

 1、儲存引擎選擇:如果數據表需要事務處理,應該考慮使用InnoDB,因為它完全符合ACID特性。如果不需要事務處理,使用默認存儲引擎MyISAM是比較明智的

 2、分表分庫,主從。

 3、對查詢進行優化,要盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引

 4、應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描

 5、應盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進行全表掃描

 6、應盡量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,將導致引擎放棄使用索引而進行全表掃描

 7、Update 語句,如果只更改1、2個字段,不要Update全部字段,否則頻繁調用會引起明顯的性能消耗,同時帶來大量日志

 8、對於多張大數據量(這里幾百條就算大了)的表JOIN,要先分頁再JOIN,否則邏輯讀會很高,性能很差。

 


免責聲明!

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



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