日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql优化数据库对象

發(fā)布時(shí)間:2023/12/14 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql优化数据库对象 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 優(yōu)化表的數(shù)據(jù)類型 表需要使用何種數(shù)據(jù)類型,是需要根據(jù)應(yīng)用來(lái)判斷的。雖然應(yīng)用設(shè)計(jì)的時(shí)候需要考慮字 段的長(zhǎng)度留有一定的冗余,但是不推薦讓很多字段都留有大量的冗余,這樣即浪費(fèi)磁盤存儲(chǔ) 空間,同時(shí)在應(yīng)用程序操作時(shí)也浪費(fèi)物理內(nèi)存。 MySQL 中,可以使用函數(shù) PROCEDURE ANALYSE()對(duì)當(dāng)前應(yīng)用的表進(jìn)行分析,該函數(shù)可 以對(duì)數(shù)據(jù)表中列的數(shù)據(jù)類型提出優(yōu)化建議,用戶可以根據(jù)應(yīng)用的實(shí)際情況酌情考慮是否實(shí)施 優(yōu)化。 以下是函數(shù) PROCEDURE ANALYSE()的使用方法: SELECT * FROM tbl_name PROCEDURE ANALYSE(); SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256); 輸出的每一列信息都會(huì)對(duì)數(shù)據(jù)表中的列的數(shù)據(jù)類型提出優(yōu)化建議。以上第二個(gè)語(yǔ)句告訴 PROCEDURE ANALYSE()不要為那些包含的值多于16個(gè)或者256字節(jié)的ENUM類型提出建議。 如果沒有這樣的限制,輸出信息可能很長(zhǎng);ENUM 定義通常很難閱讀。 根據(jù) PROCEDURE ANALYSE()函數(shù)的輸出信息,用戶可能會(huì)發(fā)現(xiàn),一些表中的字段可以修 改為效率更高的數(shù)據(jù)類型。如果決定改變某個(gè)字段的類型,則需要使用 ALTER TABLE 語(yǔ)句。 下面分析一下表 duck_cust 的數(shù)據(jù)類型是否需要優(yōu)化。 1)首先創(chuàng)建測(cè)試表 duck_custduck_cust 表中記錄了客戶的一些基本信息: drop table duck_cust; CREATE TABLE duck_cust( cust_num MEDIUMINT AUTO_INCREMENT, --客戶編號(hào) cust_title TINYINT, --客戶標(biāo)題號(hào) cust_last CHAR(20) NOT NULL, --客戶姓氏 cust_first CHAR(15) NOT NULL, --客戶名 cust_suffix ENUM('Jr.', 'II', 'III','IV', 'V', 'M.D.','PhD'), --附加碼 cust_add1 CHAR(30) NOT NULL, --客戶地址 cust_add2 CHAR(10), --客戶地址 cust_city CHAR(18) NOT NULL, --客戶所在城市 cust_state CHAR(2) NOT NULL, --客戶所在州 cust_zip1 CHAR(5)NOT NULL, --客戶郵編 cust_zip2 CHAR(4), --客戶郵編 cust_duckname CHAR(25) NOT NULL, --客戶名稱 cust_duckbday DATE, --客戶生日 PRIMARY KEY (cust_num) )TYPE=MyISAM; (2)然后生成一些測(cè)試數(shù)據(jù): INSERT INTO duck_cust VALUES(NULL, 1, 'Irishlord', 'Red', 'III', '1022 N.E. Sea of Rye', 'A207', 'Seacouver', 'WA', '98601', '3464', 'Netrek Rules', '1967:10:21'); INSERT INTO duck_cust VALUES(NULL, 4, 'Thegreat', 'Vicki', 0, '2004 Singleton Dr.', 0, 'Freedom', 'KS', '67209', '4321', 'Frida Kahlo de Tomayo', '1948:03:21'); INSERT INTO duck_cust VALUES(NULL, 9, 'Montgomery', 'Chantel', 0, '1567 Terra Cotta Way', 0, 'Chicago', 'IL', '89129', '4444', 'Bianca', '1971:07:29'); INSERT INTO duck_cust VALUES(NULL, 7, 'Robert', 'David', 'Sr.', '20113 Open Road Highway', '#6', 'Blacktop', 'AZ', '00606', '1952', 'Harley', '1949:08:00'); INSERT INTO duck_cust VALUES(NULL, 5, 'Kazui', 'Wonko', 'PhD', '42 Cube Farm Lane', 'Gatehouse', 'Vlimpt', 'CA', '45362', 0, 'Fitzwhistle', '1961:12:04'); INSERT INTO duck_cust VALUES(NULL, 6, 'Gashlycrumb', 'Karen', 0, '3113 Picket Fence Lane', 0, 'Fedora', 'VT', '41927', '5698', 'Tess D''urberville', '1948:08:19'); 這時(shí),查看一下表結(jié)構(gòu): desc duck_cust; +----------------------+----------------------------------------------+--------+-------+----------+---------+ | Field | Type | Null | Key | Default | Extra | +----------------------+----------------------------------------------+--------+-------+----------+---------+ | cust_num | mediumint(9) | | MUL | 0 | | | cust_title | tinyint(4) | YES | | NULL | | | cust_last | char(20) | | | | | | cust_first | char(15) | | | | | | cust_suffix | enum('Jr.','II','III','IV','V','M.D.','PhD') | YES | | NULL | | | cust_add1 | char(30) | | | | | | cust_add2 | char(10) | YES | | NULL | | | cust_city | char(18) | | | | | | cust_state | char(2) | | | | | | cust_zip1 | char(5) | | | | | | cust_zip2 | char(4) | YES | | NULL | | | cust_duckname | char(25) | | | | cust_duckbday | date | YES | | NULL | | +----------------------+----------------------------------------------+--------+-------+----------+---------+ (3)使用 PROCEDURE ANALYSE()函數(shù)確定要優(yōu)化的列: mysql> SELECT * FROM duck_cust PROCEDURE ANALYSE()\G; *************************** 1. row *************************** Field_name: sakila.duck_cust.cust_num Min_value: 1 Max_value: 6 Min_length: 1 Max_length: 1 Empties_or_zeros: 0 Nulls: 0 Avg_value_or_avg_length: 3.5000 Std: 1.7078 Optimal_fieldtype: ENUM('1','2','3','4','5','6') NOT NULL *************************** 2. row *************************** 從結(jié)果中,可以看到 test.duck_cust.cust_num 列的 Min_length、Max_length、 Avg_value_or_avg_length,根據(jù)這些統(tǒng)計(jì)值,可以對(duì)列進(jìn)行優(yōu)化,例如,插入的數(shù)據(jù)最大長(zhǎng)度 和最小長(zhǎng)度都是 1,所以,可以優(yōu)化字段 cust_num mediumint(2);同時(shí),上面的結(jié)果也 給出了優(yōu)化建議“Optimal_fieldtype: ENUM('1','2','3','4','5','6') NOT NULL”。 看到這個(gè)建議讀者可能會(huì)覺得很奇怪,怎么給出了枚舉類型?而不是我們預(yù)期的整型。 因?yàn)檫@時(shí)分析的測(cè)試表記錄數(shù)太少,使得 cust_name 的唯一值太少,因此函數(shù)覺得用枚舉類 型會(huì)更合理。如果是對(duì)一個(gè)大表進(jìn)行分析,提出的建議會(huì)更準(zhǔn)確。 根據(jù)給出的統(tǒng)計(jì)信息和優(yōu)化建議,可以使用如下語(yǔ)句進(jìn)行字段類型的更改: mysql> alter table duck_cust modify cust_num mediumint(2); Query OK, 6 rows affected (0.03 sec) Records: 6 Duplicates: 0 Warnings: 0 2 通過(guò)拆分提高表的訪問(wèn)效率 這里所說(shuō)的“拆分”,是指對(duì)數(shù)據(jù)表進(jìn)行拆分。有 兩種拆分方法。 (1)?第一種方法是垂直拆分,即把主碼和一些列放到一個(gè)表,然后把主碼和另外的列放 到另一個(gè)表中。 如果一個(gè)表中某些列常用,而另外一些列不常用,則可以采用垂直拆分,另外垂直 拆分可以使得數(shù)據(jù)行變小,一個(gè)數(shù)據(jù)頁(yè)就能存放更多的數(shù)據(jù),在查詢時(shí)就會(huì)減少 I/O 數(shù)。其缺點(diǎn)是需要管理冗余列,查詢所有數(shù)據(jù)需要聯(lián)合(JOIN)操作。 (2)?第二種方法是水平拆分,即根據(jù)一行或多行數(shù)據(jù)的值把數(shù)據(jù)行放到兩個(gè)獨(dú)立的表中。 水平拆分通常在以下幾種情況下使用: (a) 表很大,分割后可以降低在查詢時(shí)需要讀的數(shù)據(jù)和索引的頁(yè)數(shù),同時(shí)也降低了 索引的層數(shù),提高查詢速度。 (b) 表中的數(shù)據(jù)本來(lái)就有獨(dú)立性,例如,表中分別記錄各個(gè)地區(qū)的數(shù)據(jù)或不同時(shí)期 的數(shù)據(jù),特別是有些數(shù)據(jù)常用,而另外一些數(shù)據(jù)不常用。 ? (c) 需要把數(shù)據(jù)存放到多個(gè)介質(zhì)上。 例如,移動(dòng)電話的賬單表就可以分成兩個(gè)表或多個(gè)表。最近 3 個(gè)月的賬單數(shù)據(jù)存在一 個(gè)表中,3 個(gè)月前的歷史賬單存放在另外一個(gè)表中,超過(guò) 1 年的歷史賬單可以存儲(chǔ)到 單獨(dú)的存儲(chǔ)介質(zhì)上,這種拆分是最常使用的水平拆分方法。 水平拆分會(huì)給應(yīng)用增加復(fù)雜度,它通常在查詢時(shí)需要多個(gè)表名,查詢所有數(shù)據(jù)需 UNION 操作。在許多數(shù)據(jù)庫(kù)應(yīng)用中,這種復(fù)雜性會(huì)超過(guò)它帶來(lái)的優(yōu)點(diǎn),因?yàn)橹灰? 索引關(guān)鍵字不大,則在索引用于查詢時(shí),表中增加 2 3 倍數(shù)據(jù)量,查詢時(shí)也就增加 讀一個(gè)索引層的磁盤次數(shù),所以水平拆分要考慮數(shù)據(jù)量的增長(zhǎng)速度,根據(jù)實(shí)際情況決 定是否需要對(duì)表進(jìn)行水平拆分。 3 使用中間表提高統(tǒng)計(jì)查詢速度 對(duì)于數(shù)據(jù)量較大的表,在其上進(jìn)行統(tǒng)計(jì)查詢通常會(huì)效率很低,并且還要考慮統(tǒng)計(jì)查詢是 否會(huì)對(duì)在線的應(yīng)用產(chǎn)生負(fù)面影響。通常在這種情況下,使用中間表可以提高統(tǒng)計(jì)查詢的效率, 下面通過(guò)對(duì) session 表的統(tǒng)計(jì)來(lái)介紹中間表的使用: 1session 表記錄了客戶每天的消費(fèi)記錄,表結(jié)構(gòu)如下: CREATE TABLE session ( cust_id varchar(10) , --客戶編號(hào) cust_amount DECIMAL(16,2), --客戶消費(fèi)金額 cust_date DATE, --客戶消費(fèi)時(shí)間 cust_ip varchar(20) –客戶 IP 地址 ) 2)由于每天都會(huì)產(chǎn)生大量的客戶消費(fèi)記錄,所以 session 表的數(shù)據(jù)量很大,現(xiàn)在業(yè)務(wù)部門有 一具體的需求:希望了解最近一周客戶的消費(fèi)總金額和近一周每天不同時(shí)段用戶的消費(fèi)總金 額。針對(duì)這一需求我們通過(guò) 2 種方法來(lái)得出業(yè)務(wù)部門想要的結(jié)果。 方法 1:在 session 表上直接進(jìn)行統(tǒng)計(jì),得出想要的結(jié)果。 mysql> select sum(cust_amount) from session where cust_date>adddate(now(),-7); +------------------+ | sum(cust_amount) | +------------------+ | 161699200.64 | +------------------+ 1 row in set (3.95 sec) 方法 2:創(chuàng)建中間表 tmp_session,表結(jié)構(gòu)和源表結(jié)構(gòu)完全相同。 CREATE TABLE tmp_session ( cust_id varchar(10) , --客戶編號(hào) cust_amount DECIMAL(16,2), --客戶消費(fèi)金額 cust_date DATE, --客戶消費(fèi)時(shí)間 cust_ip varchar(20) –客戶 IP 地址 ) ; 轉(zhuǎn)移要統(tǒng)計(jì)的數(shù)據(jù)到中間表,然后在中間表上進(jìn)行統(tǒng)計(jì),得出想要的結(jié)果。 mysql> insert into tmp_session select * from session where cust_date>adddate(now(),-7); Query OK, 1573328 rows affected (6.67 sec) Records: 1573328 Duplicates: 0 Warnings: 0 mysql> select sum(cust_amount) from tmp_session; +------------------+ | sum(cust_amount) | +------------------+ | 161699200.64 | +------------------+ 1 row in set (0.73 sec) 從上面的 2 種實(shí)現(xiàn)方法上看,在中間表中做統(tǒng)計(jì)花費(fèi)的時(shí)間很少(這里不計(jì)算轉(zhuǎn)移 數(shù)據(jù)花費(fèi)的時(shí)間),另外,針對(duì)業(yè)務(wù)部門想了解“近一周每天不同時(shí)段用戶的消費(fèi)總金 額”這一需求,在中間表上給出統(tǒng)計(jì)結(jié)果更為合適,原因是源數(shù)據(jù)表(session 表) cust_date 字段沒有索引并且源表的數(shù)據(jù)量較大,所以在按時(shí)間進(jìn)行分時(shí)段統(tǒng)計(jì)時(shí)效率 很低,這時(shí)可以在中間表上對(duì) cust_date 字段創(chuàng)建單獨(dú)的索引來(lái)提高統(tǒng)計(jì)查詢的速度。 中間表在統(tǒng)計(jì)查詢中經(jīng)常會(huì)用到,其優(yōu)點(diǎn)如下: ? 中間表復(fù)制源表部分?jǐn)?shù)據(jù),并且與源表相“隔離”,在中間表上做統(tǒng)計(jì)查詢不 會(huì)對(duì)在線應(yīng)用產(chǎn)生負(fù)面影響。 ? 中間表上可以靈活的添加索引或增加臨時(shí)用的新字段,從而達(dá)到提高統(tǒng)計(jì)查詢 效率和輔助統(tǒng)計(jì)查詢作用。

總結(jié)

以上是生活随笔為你收集整理的mysql优化数据库对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。