天天看點

淺談資料庫優化mysql優化

mysql優化

一、資料庫設計原則

資料庫設計的三範式

學生表(學号,姓名,生日,課程名,課程成績,等級,學院,院長)

學号 姓名 生日 課程号 課程名 成績 等級 學院 院長
10001 張三 1998.1.1 tp3021,h333 計算機原理,高等數學 87,90 B,A 計算機學院 xxx
  • 第一範式 表中每一個屬性不可再分,不允許出現表中套表的情況
    學号 姓名 生日 課程号 成績 等級 學院 院長
    10001 張三 1998.1.1 tp3021 87 B 計算機學院 xxx
    10001 張三 1998.1.1 h333 90 A 計算機學院 xxx
    課程号 課程名
    tp3201 計算機原理
    h333 高等數學
  • 第二範式
    鍵/碼   區分不同記錄,可以一個屬性或者多個屬性的組合,主鍵是指定的鍵
    每一個非主屬性(不保含在任何一個鍵裡的屬性)必須完全依賴于主鍵(不存在非主屬性部分依賴于碼)
               
    學号 姓名 生日 學院編号
    學院編号 學院 院長
    學号 課程号 成績 等級
  • 第三範式
    第三範式: 不存在非主屬性傳遞依賴于主碼
    
               
    學号 課程号 成績
    等級編号 up down 等級
    1 100 90 A
    2 89 80 B
  • 反範式設計
    • 如果考慮查詢性能,應該盡量減少表的關聯
    • 将經常查詢的資料都放到一個表裡,盡量少采用字典表

表設計

  • 盡量選用長度小的類型
  • 能選用整型,不要選用字元串
  • 日期型能用date就不要使用datetime,不準用字元串存儲日期
  • 字段不要設定預設值null
  • 主鍵一般無意義,用整型,自增

二、sql語句的優化

1.開啟慢查詢

在mysql下查詢
mysql> show VARIABLES like '%slow%';
+---------------------------+--------------------------------+
| Variable_name             | Value                          |
+---------------------------+--------------------------------+
| log_slow_admin_statements | OFF                            |
| log_slow_slave_statements | OFF                            |
| slow_launch_time          | 2                              |慢查詢的門檻值,超過這個值認為是慢查詢
| slow_query_log            | OFF                            |慢查詢是關閉的
| slow_query_log_file       | /var/lib/mysql/ubuntu-slow.log |慢查詢日志檔案路徑
+---------------------------+--------------------------------+
5 rows in set (0.01 sec)

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

#在[mysqld]後面增加
long_query_time = 1   #超過1秒鐘的sql記錄下來
log-slow-queries = /var/mysql/log/log.txt  #慢查詢的日志檔案
log-queries-no-using-indexes   #把沒使用索引的查詢記錄下來
           

2 使用explain/desc分析sql語句

explain  select ...    #分析sql語句,sql語句本身并不執行
explain select name ,age from user where age >10
    -> ;
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | user  | range | index_age     | index_age | 2       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
1 row in set (0.00 sec)
select_type  :  查詢的類型  
              simple 指單表查詢(不使用連接配接、子查詢)
              primary: 主查詢
              union  聯合查詢的第二個sql語句,或後面的查詢
              subquery  子查詢
table   表名
type    查詢方式:
	all
		全表掃描,對于資料表從頭到尾找一遍
		如果有limit限制,則找到之後就不在繼續向下掃描
			select * from tb1 where email = '[email protected]'
			select * from tb1 where email = '[email protected]' limit 1;
				找到一個後就不再繼續掃描
	index
		全索引掃描,對索引從頭到尾找一遍
			select id from student;
	range
		對索引列進行範圍查找
	index_merge
		合并索引,使用多個單列索引搜尋
	ref_or_null
	ref
		根據索引查找一個或多個值
	eq_ref
		連接配接時使用primary key 或 unique類型
	const
		常量
		表最多有一個比對行,因為僅有一行,在這行的列值可被優化器剩餘部分認為是常數,const表很快,
		因為它們隻讀取一次
	system
		系統,表僅有一行(=系統表)。這是const聯接類型的一個特例
	性能
		all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
 possible_keys  可能被用到的索引
 key             使用的索引
 key_len         索引字段最大使用長度
 rows            影響的行數,越小越好
 
 關注:type 、key、rows
 
           

3 優化sql語句

1 查詢的時候不要使用select *
2.盡量使用limit 1 取得唯一的一行
3.盡量使用索引字段進行查詢
4 可以使用覆寫索引加速查詢  (一個索引包含了查詢結果中所有的字段)
5 盡量少用like 或者or
6 不要使用全文索引,如果非要使用可以把全文索引獨立出來,建立全文索引伺服器
7 關聯查詢的時候,關聯的字段都應該有索引
8 不要使用!=操作,不使用索引
9 查詢的時候類型不比對不使用索引
10 聯合索引不帶左字首,不使用索引
11 盡量減少子查詢,可以使用關聯查詢代替子查詢
    select count(*) from article where uid in(select uid from user where id=10)
    select count(*) from aticle,user where user.id = aticle.uid   and user.id=10
    select count(*) from aticle join user on user.id=article.uid  where userid.id=10
12 盡量多試驗不同sql語句,比較他們的效率,采用最少
13 不要在where中,運算符左邊運算,隻要是計算,不采用索引
    select username from user where age/2>10
14 不要在where中,運算符左邊不要出現任何函數,否則不采用索引
   select COUNT(*) from user where year(birthday) == 1993;
15 避免預設排序
    select cid,count(*) from bbs group by cid
    select cid,count(*) from bbs group by cid order by null #不排序
           

4 其他優化措施

在應用層面可以nosql技術,把資料儲存redius、memcached中加速查詢
從架構方面:讀寫分離
可以使用mysql分區技術,把一個表分為多個檔案
分庫分表分機器
把表進行垂直切分,或水準切分

           

資料庫設計 ====》索引 ===》SQL語句優化 ===》分區=》nosql緩存 ==》讀寫分離=》分庫分表分機器(資料庫中間件)=》表的垂直/水準切分

其他技術

1. 存儲過程

2. 觸發器

3. 資料分區

4. 讀寫分離

5. 主從複制