久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    Mysql數據庫性能優化一

     WindySky 2016-04-13
    今天,數據庫的操作越來越成為整個應用的性能瓶頸了,這點對于Web應用尤其明顯。關于數據庫的性能,這并不只是DBA才需要擔心的事,而這更是我們程序員需要去關注的事情

    今天,數據庫的操作越來越成為整個應用的性能瓶頸了,這點對于Web應用尤其明顯。關于數據庫的性能,這并不只是DBA才需要擔心的事,而這更是我們程序員需要去關注的事情。當我們去設計數據庫表結構,對操作數據庫時(尤其是查表時的SQL語句),我們都需要注意數據操作的性能。這里,我們不會講過多的SQL語句的優化,而只是針對MySQL這一Web應用最多的數據庫。

    mysql的性能優化無法一蹴而就,必須一步一步慢慢來,從各個方面進行優化,最終性能就會有大的提升。

    Mysql數據庫的優化技術

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

    ·表的設計合理化(符合3NF)

    ·添加適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引]

    ·分表技術(水平分割、垂直分割)

    ·讀寫[寫: update/delete/add]分離

    ·存儲過程 [模塊化編程,可以提高速度]

    ·對mysql配置優化 [配置最大并發數my.ini, 調整緩存大小 ]

    ·mysql服務器硬件升級

    ·定時的去清除不需要的數據,定時進行碎片整理(MyISAM)

    數據庫優化工作

    對于一個以數據為中心的應用,數據庫的好壞直接影響到程序的性能,因此數據庫性能至關重要。一般來說,要保證數據庫的效率,要做好以下四個方面的工作:

    ① 數據庫設計

    ② sql語句優化

    ③ 數據庫參數配置

    ④ 恰當的硬件資源和操作系統

    此外,使用適當的存儲過程,也能提升性能。

    這個順序也表現了這四個工作對性能影響的大小

    數據庫表設計

    通俗地理解三個范式,對于數據庫設計大有好處。在數據庫設計中,為了更好地應用三個范式,就必須通俗地理解三個范式(通

    俗地理解是夠用的理解,并不是最科學最準確的理解):

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

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

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

    但是,沒有冗余的數據庫未必是最好的數據庫,有時為了提高運行效率,就必須降低范式標準,適當保留冗余數據。具體做法是: 在概念數據模型設計時遵守第三范式,降低范式標準的工作放到物理數據模型設計時考慮。降低范式就是增加字段,允許冗余。

    數據庫的分類

    關系型數據庫: mysql/oracle/db2/informix/sysbase/sql server

    非關系型數據庫: (特點: 面向對象或者集合)

    NoSql數據庫: MongoDB(特點是面向文檔)

    舉例說明什么是適度冗余,或者說有理由的冗余!


    上面這個就是不合適的冗余,原因是:

    在這里,為了提高學生活動記錄的檢索效率,把單位名稱冗余到學生活動記錄表里。單位信息有500條記錄,而學生活動記錄在

    一年內大概有200萬數據量。 如果學生活動記錄表不冗余這個單位名稱字段,只包含三個int字段和一個timestamp字段,只占用了16字節,是一個很小的表。而冗余了一個 varchar(32)的字段后則是原來的3倍,檢索起來相應也多了這么多的I/O。而且記錄數相差懸殊,500 VS 2000000 ,導致更新一個單位名稱還要更新4000條冗余記錄。由此可見,這個冗余根本就是適得其反。



    訂單表里面的Price就是一個冗余字段,因為我們可以從訂單明細表中統計出這個訂單的價格,但是這個冗余是合理的,也能提升查詢性能。

    從上面兩個例子中可以得出一個結論:

    1---n 冗余應當發生在1這一方.

    SQL語句優化

    SQL優化的一般步驟

    1.通過show status命令了解各種SQL的執行頻率。

    2.定位執行效率較低的SQL語句-(重點select)

    3.通過explain分析低效率的SQL

    4.確定問題并采取相應的優化措施

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    -- select語句分類
    Select
    Dml數據操作語言(insert update delete)
    dtl 數據事物語言(commit rollback savepoint)
    Ddl數據定義語言(create alter drop..)
    Dcl(數據控制語言) grant revoke
    -- Show status 常用命令
    --查詢本次會話
    Show session status like 'com_%'; //show session status like 'Com_select'
    --查詢全局
    Show global status like 'com_%';
    -- 給某個用戶授權
    grant all privileges on *.* to 'abc'@'%';
    --為什么這樣授權 'abc'?表示用戶名 '@' 表示host, 查看一下mysql->user表就知道了
    --回收權限
    revoke all on *.* from 'abc'@'%';
    --刷新權限[也可以不寫]
    flush privileges;

    SQL語句優化-show參數

    MySQL客戶端連接成功后,通過使用show [session|global] status 命令可以提供服務器狀態信息。其中的session來表示當前的連接的統計結果,global來表示自數據庫上次啟動至今的統計結果。默認是session級別的。

    下面的例子:

    show status like 'Com_%';

    其中Com_XXX表示XXX語句所執行的次數。

    重點注意:Com_select,Com_insert,Com_update,Com_delete通過這幾個參數,可以容易地了解到當前數據庫的應用是以插入更新為主還是以查詢操作為主,以及各類的SQL大致的執行比例是多少。

    還有幾個常用的參數便于用戶了解數據庫的基本情況。

    Connections:試圖連接MySQL服務器的次數

    Uptime:服務器工作的時間(單位秒)

    Slow_queries:慢查詢的次數 (默認是慢查詢時間10s)

    1
    2
    3
    show status like 'Connections'
    show status like 'Uptime'
    show status like 'Slow_queries'

    如何查詢mysql的慢查詢時間

    1
    Show variables like 'long_query_time';

    修改mysql 慢查詢時間

    1
    set long_query_time=2

    SQL語句優化-定位慢查詢

    問題是: 如何從一個大項目中,迅速的定位執行速度慢的語句. (定位慢查詢)

    首先我們了解mysql數據庫的一些運行狀態如何查詢(比如想知道當前mysql運行的時間/一共執行了多少次

    select/update/delete.. / 當前連接)

    為了便于測試,我們構建一個大表(400 萬)-> 使用存儲過程構建

    默認情況下,mysql認為10秒才是一個慢查詢.

    修改mysql的慢查詢.

    1
    2
    show variables like 'long_query_time' ; //可以顯示當前慢查詢時間
    set long_query_time=1 ;//可以修改慢查詢時間

    構建大表->大表中記錄有要求, 記錄是不同才有用,否則測試效果和真實的相差大.創建:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    CREATE TABLE dept( /*部門表*/
    deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*編號*/
    dname VARCHAR(20) NOT NULL DEFAULT "", /*名稱*/
    loc VARCHAR(13) NOT NULL DEFAULT "" /*地點*/
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
    CREATE TABLE emp
    (empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 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;

    測試數據

    1
    2
    3
    4
    5
    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 $$
    創建函數,該函數會返回一個指定長度的隨機字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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

    創建一個存儲過程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    create procedure insert_emp(in start int(10),in max_num int(10))
    begin
    declare i int default 0;
    #set autocommit =0 把autocommit設置成0
    set autocommit = 0;
    repeat
    set i = i + 1;
    insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand());
    until i = max_num
    end repeat;
    commit;
    end
    #調用剛剛寫好的函數, 1800000條記錄,從100001號開始
    call insert_emp(100001,4000000);

    這時我們如果出現一條語句執行時間超過1秒中,就會統計到.

    如果把慢查詢的sql記錄到我們的一個日志中

    在默認情況下,低版本的mysql不會記錄慢查詢,需要在啟動mysql時候,指定記錄慢查詢才可以

    bin\mysqld.exe - -safe-mode - -slow-query-log [mysql5.5 可以在my.ini指定]

    bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]

    該慢查詢日志會放在data目錄下[在mysql5.0這個版本中時放在 mysql安裝目錄/data/下],在 mysql5.5.19下是需要查看

    my.ini 的 datadir="C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/“來確定.

    在mysql5.6中,默認是啟動記錄慢查詢的,my.ini的所在目錄為:C:\ProgramData\MySQL\MySQL Server 5.6,其中有一個配置項

    slow-query-log=1

    針對 mysql5.5啟動慢查詢有兩種方法

    bin\mysqld.exe - -safe-mode - -slow-query-log

    也可以在my.ini 文件中配置:

    1
    2
    3
    4
    [mysqld]
    # The TCP/IP Port the MySQL Server will listen on
    port=3306
    slow-query-log

    通過慢查詢日志定位執行效率較低的SQL語句。慢查詢日志記錄了所有執行時間超過long_query_time所設置的SQL語句。

    1
    2
    show variables like 'long_query_time';
    set long_query_time=2;

    為dept表添加數據

    1
    2
    3
    4
    5
    6
    7
    desc dept;
    ALTER table dept add id int PRIMARY key auto_increment;
    CREATE PRIMARY KEY on dept(id);
    create INDEX idx_dptno_dptname on dept(deptno,dname);
    INSERT into dept(deptno,dname,loc) values(1,'研發部','康和盛大廈5樓501');
    INSERT into dept(deptno,dname,loc) values(2,'產品部','康和盛大廈5樓502');
    INSERT into dept(deptno,dname,loc) values(3,'財務部','康和盛大廈5樓503');UPDATE emp set deptno=1 where empno=100002;

    ****測試語句***[對emp表的記錄可以為3600000 ,效果很明顯慢]

    1
    select * from emp where empno=(select empno from emp where ename='研發部')

    如果帶上order by e.empno 速度就會更慢,有時會到1min多.

    測試語句

    1
    select * from emp e,dept d where e.empno=100002 and e.deptno=d.deptno;

    查看慢查詢日志:默認為數據目錄data中的host-name-slow.log。低版本的mysql需要通過在開啟mysql時使用- -log-slow-queries[=file_name]來配置

    SQL語句優化-explain分析問題

    1
    Explain select * from emp where ename=“wsrcla”

    會產生如下信息:

    select_type:表示查詢的類型。

    table:輸出結果集的表

    type:表示表的連接類型

    possible_keys:表示查詢時,可能使用的索引

    key:表示實際使用的索引

    key_len:索引字段的長度

    rows:掃描出的行數(估算的行數)

    Extra:執行情況的描述和說明



    explain select * from emp where ename='JKLOIP'

    如果要測試Extra的filesort可以對上面的語句修改

    1
    explain select * from emp order by ename\G

    EXPLAIN詳解

    id

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

    id 示例

    1
    SELECT * FROM emp WHERE empno = 1 and ename = (SELECT ename FROM emp WHERE empno = 100001) \G;

    select_type

    PRIMARY :子查詢中最外層查詢

    SUBQUERY : 子查詢內層第一個SELECT,結果不依賴于外部查詢

    DEPENDENT SUBQUERY:子查詢內層第一個SELECT,依賴于外部查詢

    UNION :UNION語句中第二個SELECT開始后面所有SELECT,

    SIMPLE

    UNION RESULT UNION 中合并結果

    Table

    顯示這一步所訪問數據庫中表名稱

    Type

    對表訪問方式

    ALL:

    1
    SELECT * FROM emp \G

    完整的表掃描 通常不好

    1
    SELECT * FROM (SELECT * FROM emp WHERE empno = 1) a ;

    system:表僅有一行(=系統表)。這是const聯接類型的一個特

    const:表最多有一個匹配行

    Possible_keys

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

    Key

    Mysql 從 Possible_keys 所選擇使用索引

    Rows

    估算出結果集行數

    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:不用讀取表中所有信息,僅通過索引就可以獲取所需數據;

    以上所述是小編給大家介紹的Mysql數據庫性能優化一 ,下篇文章繼續給大家介紹mysql數據庫性能優化二,希望大家持續關注本站最新內容!

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 亚洲综合无码精品一区二区三区| 亚洲更新最快无码视频| 久久五十路丰满熟女中出| 2020国产激情视频在线观看| 四虎影视永久无码精品| 日韩精品一区二区三区影院| 久久精品国产一区二区三区| 亚欧乱色熟女一区二区三区| 天堂中文8资源在线8| 少妇又爽又刺激视频| 国产精品无码久久综合网 | 国产精品免费看久久久| 国产美女被遭强高潮免费一视频| 韩国三级理论无码电影在线观看| 丰满人妻AV无码一区二区三区| 大学生被内谢粉嫩无套| 亚洲精品一区二区妖精| 国产成人一区二区三区视频免费| 中文字幕在线观看| 人人人澡人人肉久久精品| 99久久免费精品国产72精品九九| 国产精品视频亚洲二区| 宅男666在线永久免费观看| 偷拍专区一区二区三区| 撕开奶罩揉吮奶头高潮AV| 怡红院一区二区三区在线| 午夜精品久久久久成人| 亚洲AV午夜成人无码电影| 日韩中文字幕av有码| 国产乱子影视频上线免费观看| 人人澡人摸人人添| 久久精品国产亚洲av麻豆软件| 狠狠婷婷色五月中文字幕| 国产成人一区二区不卡| 日本一卡2卡3卡4卡5卡精品视频| 久久综合狠狠综合久久| 亚洲国产精品久久久天堂麻豆宅男| 国产成人精品综合在线观看| 国产精品福利自产拍在线观看| 日本一区二区三区专线| 亚洲精品国模一区二区|