1. 程式人生 > >常見mysql優化 面試題

常見mysql優化 面試題

優化哪些方面

1.表設計上

       正規化,儲存引擎,欄位型別

2.功能上

       索引,快取,分割槽

3.sql語句上

       合理sql,經驗

4.架構上

       主從複製,負載均衡,讀寫分離

儲存引擎

儲存引擎是真正儲存資料的地方

Mysql 5.5

1 不支援事務

2 表級鎖

3 資料和索引是分開儲存

4  insert ,select 適合高速插入和檢索。(bbs,部落格)

5 可壓縮

6 全文索引(全文搜尋)full index

快 糙 猛  php  mysql

壓縮

INnodb

*************************** 8. row ***************************

      Engine: InnoDB

  1. 事務處理
  2. 行級鎖  併發性
  3. 按照主鍵排序
  4. 外來鍵,維護資料完整性  (逐漸淡化)
  5. 考慮CPU效率和處理大資料的最佳效能
  6. 資料和索引一塊儲存
  7. 5.6.4開始支援全文索引

Innodb表的檔案

ibdata1  這是所有的innodb表的表空間檔案  

開啟這個選項(mysql 5.6自動開啟)

mysql> show variables like 'innodb_file_per_table%';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| innodb_file_per_table | ON    |

+-----------------------+-------+

1 row in set (0.00 sec)

鎖的概念

出現爭奪資源。

讀鎖.    共享鎖.   一個程序在讀取某表的時候,另一個程序也可以讀取.但是當前程序僅僅能讀取這個表,而不能操作其他表.

寫鎖.     獨佔鎖.  一個程序在寫表時,是不允許另一個程序寫,當前程序僅僅能操作這一個表.

鎖的範圍,精細程度上。

Myisam表是表級鎖。    Innodb是行級鎖。

表級鎖:  開銷小,加鎖時間短。

行級鎖:相反。

Myisam和innodb的比較

Innodb:資料完整性,併發性好。事務,且是預設表引擎

適合銀行轉賬,等資料安全要求高的應用

  • Myisam:壓縮儲存,適合 insert和select多的應用,部落格,BBS等
  • 高速併發插入,
  • 壓縮:
  • 壓縮後的資料
  • 壓縮後,不能再對錶進行寫操作
  • 解壓縮

除非考慮到innodb不支援的特性,否則就優先選擇innodb儲存引擎。

其他的儲存引擎

  • Archive
    • 歸檔型。  Insert  select 日誌
  • Memory
    • 記憶體型.支援insert,update,delete,select.資料不能過大。
  • merge
    • 合併多個相同結構的myisam表。
    • 應用於 專案中的水平拆分。單表記錄過大。

索引

索引也是一種結構。從資料記錄裡提取出關鍵字,可以是某列,某些列,或者是列的一部分。關鍵字和資料記錄仍然保持原來的關聯關係。

刪除索引

alter table mycom drop index comnum

去除索引的情況

索引的種類

索引  某列,某些列,某列的部分。

  1. Primary 主鍵索引   不重複,不為空,不能為0   
  2. Key 普通索引  沒什麼要求
  3. Unique 唯一索引  不重複,可以為null,
  4. Fulltext  全文索引    列是 varchar,char,text.沒什麼要求。 關鍵字來自列的部分

共同點:都是從資料記錄裡提取出的關鍵字。都為了查詢提速。

差異性:就是關鍵字的要求不同。

複合索引。 關鍵字來源於多個列。

字首索引。 關鍵字來自於某列的前N個字元。

索引的使用

@ SQL執行計劃  explain

使用索引時的情況。

explain select * from mycom where con=12345656

沒有使用索引時的結果

Mysql 5.5之前,explain只能針對select,現在insert ,update,delete都可以。

@  檢索資料時使用  where  

Where  欄位名=欄位值,

加索引的列,數值分佈比較廣泛。Where sex=’1’分佈不廣泛。

索引是佔據硬碟空間。影響寫資料的速度。

@  排序時也可以使用  order by

排序欄位comname加上了索引後

Using  filesort  排序 。外部排序(硬碟上,mysql使用order by ). (內部排序,氣泡排序是一個例子)

@索引覆蓋

查詢時索引覆蓋了資料。

查詢的資料,直接在索引中就有,而索引在記憶體中,查詢時候不需要去資料區中檢索,直接在索引中就可以查到。

使用索引需要注意的地方

列獨立

左原則

複合索引中,查詢時只要用到了最左邊的列,就能應用上索引。  

Like   ‘abc%’,’abcd_%’ 只要以確定的字元開始的,也可以使用索引。

Order by

Or

Or兩端的欄位,必須都建立索引,才有可能使用。

列型別是字串,字元常量沒有使用引號

Name Varchar,char(),’abcdef’,’123456’ 

Select * from user where name=’123456’ //name欄位建立索引,就會使用。

Select * from user where name=123456 //有可能不使用索引

存在索引,使用也正確,但是不使用

Select * from user where col>1 and <90 (均勻分佈時)

 Select * from mycom where comnum > 12990

Mysql智慧化的選擇結果。

Mysql覺得 在索引和資料之間來回切換,造成的開銷比實際使用索引要大,放棄使用索引。

全文索引

解決like

Like  ‘%美食%’;

Field  regexp  ‘’;

全表掃描。

Fulltext  

使用全文索引的方式查詢

全文索引預設不支援中文,因為:

  1. 英文天然以空格為區分,分割符。中文沒有。
  2. 中文分詞。有一套關鍵字詞庫。
  3. Sphinx,可以作為mysql外掛來使用。只支援俄文和英文,Coreseek中文包。
  4. lucence
  5. 核心功能:建立全文索引,中文分詞。

字首索引

關鍵字的提取,是某個列的前N個字元

前N個字元,所達到的辨識度無限接近於使用整個欄位達到的辨識度。

Create Index  索引名  on  表名  (field(N))

N到底是多少?

經過測試 N=9

Create  index preindex on mycom (pass(9))

索引覆蓋。應用不了字首索引。

其他優化的地方

只查詢相關的列

Select id,name,

一旦涉及到資料庫遷移,或者表結構修改等情況下,會造成大面積的修改程式碼。

慎用select  *

節省頻寬的功能。

分解複雜查詢

禁用子查詢,join.。這些操作涉及鎖。影響併發。

不宜建立索引的列

優化group by

使用order by null 避免group by 時預設的排序

優化insert

Insert into test values(1,2),(3,4) 多個value的情況

分割槽

適合資料量1億條以上的表。

Mysql 5.1

Show variables  like ‘%partition%’

Show plugins;

*************************** 42. row ***************************

   Name: partition

 Status: ACTIVE

   Type: STORAGE ENGINE

Library: NULL

License: GPL

Partition  

分割槽語法

Create  table

Key(),hash(),list(),range()

查詢快取

mysql> show variables like '%query_cache%';

+------------------------------+---------+

| Variable_name                | Value   |

+------------------------------+---------+

| have_query_cache             | YES     |

| query_cache_limit            | 1048576 |

| query_cache_min_res_unit     | 4096    |

| query_cache_size             | 1048576 |

| query_cache_type             | OFF     |    //是否開啟查詢快取

| query_cache_wlock_invalidate | OFF     |

+------------------------------+---------+

6 rows in set (0.00 sec)

需要在配置檔案設定 query_cache_type=On|1

慢查詢日誌

可以為當前程序開啟。

慢查詢日誌,不是優化措施,它可以幫助我們找到那些查詢超過某個時間點的SQl語句。