目前看: 網站的開發瓶頸
1. 帶寬-雲計算,雲終端(視屏網站)
2. 數據庫-網站大併發,海量存儲(sina,sohu )
話題 :怎樣做,我們的數據庫會更快!
數據庫分類:
關係型數據庫: mysql、oracle、sql server、db2、informix
非關係型數據: 面向集合,面向對象…
nosql數據庫: mongodb PHP項目
u 數據庫優化應當考慮方面:
1. 數據庫的設計(表)->符號3NF(有時候反3NF)
2. select語句 ->重點(如何定位慢查詢)
3. 數據庫參數設置.
4. 配套硬件的設置(CPU、內存)
u 數據庫的設計
1.我們的數據表要滿足1NF, 含義是:
表中的每條記錄是原子性約束 2. 只要數據庫是關係型數據庫,就滿足1NF
2.2NF 二範式
表中的記錄,不能夠出現完全一樣的記錄,就滿足了二範式,一般說是通過設置主鍵來完成.
3. 3NF, 三範式
表中的某個字段的信息,可以推導得出,不要出現冗餘數據.
比如下面就是不滿足3NF
但是,規定是死的,技術是需要靈活使用.
u sql語句的優化-針對Mysql
1. 通過 show status 可以查看當前Mysql的一些情況.
比如: 看看mysql一共執行了多少次 增,刪,改,查
show session status like ‘com_select’; 【這個指令用於查看,當前會話,執行了多少次select】
show session status like ‘com_update’; //delete /insert
如果你希望查看的是數據庫從啓動到目前執行的情況則,命令應該這樣寫:
show global status like ‘com_update’; //delete /inser
Connections:試圖連接MySQL服務器的次數
show status like ‘Connections’;
Uptime:服務器工作的時間(單位秒)
Slow_queries:慢查詢的次數 (默認是慢查詢時間10s) [重要的知識點: 如何找到慢查詢]
2. 在對mysql的select 語句進行優化時,我們使用的工具是explain(具體說)
u 如何定位慢查詢
1.任務:做一張1800000 記錄的大表
使用的是自寫的腳本.(介紹Mysql的存儲過程和自定義函數)
<?php
$con=mysql_connect();
if(!$con){
exit;
}
//msql_select_db(“temp”,$con);
$sql=”select temp.rand_string();”
?>
查詢的慢日誌,默認是放在 my.ini文件 :
datadir="C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/"
2. 如果在工作中,需要去記錄慢查詢,則我們啓動mysql的方式是這樣
dos>bin\mysqld.exe --slow-query-log
3. 用一個指令可以查看當前慢查詢的時間 ,默認10s
show variables like ‘slow_query_time’;
如果 測試,我們可以把這個默認的慢查詢時間10s->1s
set long_query_time=1;
4. 當你的查詢時間查過了1s ,則在
datadir="C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/"
就有日誌文件itcast-211b4ff3-slow.log
就記錄了.
u Explain 的使用
基本用法是
explain sql語句;
作用是:通過explain 可以看到Mysql數據庫將怎樣執行你的sql語句
extra表示額外信息 (比如 where , filesort ,temp表)
rows: 修改一下說法(圖上有點錯誤): 估算出結果集行數
我們使用子查詢時,會創建臨時表, 臨時表的效率相對比較低, 我們建議使用 left join 來完成完成查詢.
舉例:
//查詢辦公地點在北京的 所有僱員
explain select * from emp where emp.deptno=(select * from dept where loc=’bj’);
select * from 表1 left join 表2 on 連接條件 where 更多條件
更詳細的說明
n Explain select * from emp where ename=“zrlcHd”
會產生如下信息:
select_type:表示查詢的類型。
table:輸出結果集的表
type:表示表的連接類型
possible_keys:表示查詢時,可能使用的索引
key:表示實際使用的索引
key_len:索引字段的長度
rows:掃描的行數
Extra:執行情況的描述和說明
u 如何給表提速
MyISAM數據表,有三個文件, *.frm , *.myd , *.myi
創建索引:
基本語法:
create index 索引名 on 表名(字段);
實際案例:
create index myind1 on emp(ename);
u 哪些字段不要建立索引
1. 唯一性差的字段不要建立索引 [sex ‘男’]
2. 變化頻繁的字段不要建立索引 [用戶在線狀態] [update]
3. 在where條件中,很少出現的不要建立索引.
4. 在where條件中經常出現,同時不滿足上面3個條件就應當建立索引.
u 索引的分類
1. 主鍵索引(只有這個字段,被設置成主鍵,則自動成爲主鍵索引, 在一張中只能有一個主鍵索引) primary key 是可以多個列構造.
2. 唯一索引(UNIQUE)
create table bbb( id int primary key auto_increment, name varchar(20) unique);
insert into aaa values(1,’aa’);
insert into aaa values(1,’bb’); (x)
insert into aaa values(null,’cc’);
insert into aaa values(2,’aa’);(x)
insert into aaa values(3,null);
insert into aaa values(4,null);
主鍵和UNIQUE的比較
① 主鍵不能重複,也不能爲NULL
② UNIQUE不能重複,但是可以爲NULL
3. 普通索引
4. 全文索引(FULLTEXT). ->在MySql -》sphinx (中文分詞)/ coreseek
create fulltext index on news (content)
select * from news where content like ‘大暴雨%’
u 創建索引
1. 主鍵索引創建
創建表的時候,就指定主鍵
create table aaa100(id int primary key ,name varchar(20) );
如果是複合主鍵
create table aaa100(id int ,name varchar(20), primary key (id,name) );
如果表已經創建好,然後通過修改的方法來添加主鍵索引.
ALTER TABLE emp ADD PRIMARY KEY (empno);
2. 唯一索引的創建
create unique index 索引名 on 表名(字段名);
3. 普通索引
create index 索引名 on 表名(字段名);
4. 全文索引
create fulltext index 索引名 on 表名(字段名);
u 查詢索引
三種方法:
show index form 表名
show keys from 表名
desc 表名
u 修改索引
alter 。。
刪除索引,重新創建
u 刪除索引
drop index 索引名 on 表名
alter table 表名 drop index索引名;
刪除主鍵索引
alter table 表名 drop primary key;
u 如何正確使用索引,和注意事項
1. 如果你創建的索引是複合索引:
alter table dept add index myind (dname,loc);
那麼當select 語句用到左邊的列時,纔用到該索引.
2. 在使用like語句查詢時,當 like ‘%aa’ 就不能使用到索引了
3. 在select 語句,儘量不要使用or 語句,因爲這個關鍵字,會讓索引失效.(比如 where 條件中有三個 字端有兩個是索引字段,但是有一個不是索引,導致一個索引都不要.)
4. 一會說: 意思: 建議 在mysql不管這個字段是數值,還是字符串,建議大家 使用’’引用一下.
5. 如果mysql發現掃描全部表,比通過索引查詢還快,就會不使用索引
u 小技巧
關於group by的優化
如果只希望分組,但不希望排序可以使用 order by null 來禁用排序
explain select *from dept group by loc order by null\G
u 有些情況下,可以使用連接來替代子查詢。(在實際開發中,使用left join 來替代案例到時在想),因爲使用join,MySQL不需要在內存中創建臨時表。(講解)
u MyISAM和INNODB的選擇
如果我們查詢某張表頻繁,同時對該表不需要太多的事務處理,則考試使用MyISAM
如果對某表操作是,對事務要求高,則使用INNODB
事務(1. commit 2. rollback, 3 savepoint)
MyISAM>INNODB
一個項目中,可以更加實際情況來決定,表使用什麼存儲引擎.
u 關於字段類型選擇
對應數值精度要求高的 建議使用 deciaml ,不要使用float
對應存儲引擎是MyISAM類型的,我們要定時對它優化. *.MYD
optimize table 表名 [優化]
u 日期類型要根據實際需要選擇能夠滿足應用的最小存儲的早期類型
這裏說明一下datetime 和 timestamp區別:
timestamp 是會跟着你的update變化的.
我建議大家 關於時間字段,可以使用 datetime , 也可以使用int
提出一個: 如果取出 一個小時內的新貼.
time()-3600*30
mysql函數-》DEDE [日期函數]
補充: datetime 這樣就可以使用Mysql數據庫提供的日期函數.
create table bbs(id int primary key, poster varchar(32), content varchar(1024),posttime datetime);
//請查詢1個小時內,發的最新帖子
最重要的函數是 DATE_ADD(時間,間隔時間); | DATE_SBU
select * from bbs where DATE_ADD(now(),interval -1 hour) < posttime;
u 表的水平劃分
所謂表的水平分割,指的是:把一張大表,根據某個標準(實際來定),分割成小表,各個表的結構都是一樣的! (關鍵點是,找到分割表的標準)
u 表的垂直分割