MySQL優化
對mysql優化時一個綜合性的技術,主要包括 a: 表的設計合理化(符合3NF) b: 新增適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引] c: 分表技術(水平分割、垂直分割) d: 讀寫[寫: update/delete/add]分離 e: 儲存過程 [模組化程式設計,可以提高速度] f: 對mysql配置優化 [配置最大併發數my.ini, 調整快取大小 ] g: mysql伺服器硬體升級 h: 定時的去清除不需要的資料,定時進行碎片整理(MyISAM) 什麼樣的表才是符合3NF (正規化) 表的正規化,是首先符合1NF, 才能滿足2NF , 進一步滿足3NF 1NF: 即表的列的具有原子性,不可再分解,即列的資訊,不能分解, 只有資料庫是關係型資料庫(mysql/oracle/db2/informix/sysbase/sql server),就自動的滿足1NF ☞ 資料庫的分類 關係型資料庫: mysql/oracle/db2/informix/sysbase/sql server 非關係型資料庫: (特點: 面向物件或者集合) NoSql資料庫: MongoDB(特點是面向文件) 2NF: 表中的記錄是唯一的, 就滿足2NF, 通常我們設計一個主鍵來實現 3NF: 即表中不要有冗餘資料, 就是說,表的資訊,如果能夠被推匯出來,就不應該單獨的設計一個欄位來存放. 比如下面的設計就是不滿足3NF: 反3NF : 但是,沒有冗餘的資料庫未必是最好的資料庫,有時為了提高執行效率,就必須降低正規化標準,適當保留冗餘資料。具體做法是: 在概念資料模型設計時遵守第三正規化,降低正規化標準的工作放到物理資料模型設計時考慮。降低正規化就是增加欄位,允許冗餘。 案例 : Sql語句本身的優化 問題是: 如何從一個大專案中,迅速的定位執行速度慢的語句. (定位慢查詢) ①首先我們瞭解mysql資料庫的一些執行狀態如何查詢(比如想知道當前mysql執行的時間/一共執行了多少次select/update/delete.. / 當前連線) show status 常用的: show status like ‘uptime’ ; showstauts like ‘com_select’show stauts like ‘com_insert’ ...類推 updatedelete ☞ show [session|global] status like .... 如果你不寫[session|global] 預設是session 會話,指取出當前視窗的執行,如果你想看所有(從mysql 啟動到現在,則應該 global) show status like ‘connections’; //顯示慢查詢次數 show status like ‘slow_queries’; ②如何去定位慢查詢 構建一個大表(400 萬)-> 儲存過程構建 預設情況下,mysql認為10秒才是一個慢查詢. 修改mysql的慢查詢. show variables like ‘long_query_time’ ; //可以顯示當前慢查詢時間 set long_query_time=1 ;//可以修改慢查詢時間 構建大表->大表中記錄有要求, 記錄是不同才有用,否則測試效果和真實的相差大. 建立: CREATE TABLE dept( /*部門表*/ deptno MEDIUMINTUNSIGNEDNOT NULLDEFAULT 0,/*編號*/ dname VARCHAR(20)NOT NULLDEFAULT "", /*名稱*/ loc VARCHAR(13) NOT NULL DEFAULT "" /*地點*/ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; CREATE TABLE emp (empnoMEDIUMINT UNSIGNEDNOT NULLDEFAULT 0, /*編號*/ ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/ job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/ mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上級編號*/ hiredate DATE NOT NULL,/*入職時間*/ sal DECIMAL(7,2)NOT NULL,/*薪水*/ comm DECIMAL(7,2) NOT NULL,/*紅利*/ deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部門編號*/ )ENGINE=MyISAM DEFAULT CHARSET=utf8 ; CREATE TABLE salgrade ( grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, losal DECIMAL(17,2)NOT NULL, hisal DECIMAL(17,2)NOT NULL )ENGINE=MyISAM DEFAULT CHARSET=utf8; 測試資料 INSERT INTO salgrade VALUES (1,700,1200); INSERT INTO salgrade VALUES (2,1201,1400); INSERT INTO salgrade VALUES (3,1401,2000); INSERT INTO salgrade VALUES (4,2001,3000); INSERT INTO salgrade VALUES (5,3001,9999); 為了儲存過程能夠正常執行,我們需要把命令執行結束符修改 delimiter $$ create function rand_string(n INT) returns varchar(255) #該函式會返回一個字串 begin #chars_str定義一個變數 chars_str,型別是 varchar(100),預設值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; declare chars_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; declare return_str varchar(255) default ''; declare i int default 0; while i < n do set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1)); set i = i + 1; end while; return return_str; end $$ 如果希望在程式中使用,是Ok!