mysql优化数据库对象
生活随笔
收集整理的這篇文章主要介紹了
mysql优化数据库对象
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 優化表的數據類型
表需要使用何種數據類型,是需要根據應用來判斷的。雖然應用設計的時候需要考慮字
段的長度留有一定的冗余,但是不推薦讓很多字段都留有大量的冗余,這樣即浪費磁盤存儲
空間,同時在應用程序操作時也浪費物理內存。
在 MySQL 中,可以使用函數 PROCEDURE ANALYSE()對當前應用的表進行分析,該函數可
以對數據表中列的數據類型提出優化建議,用戶可以根據應用的實際情況酌情考慮是否實施
優化。
以下是函數 PROCEDURE ANALYSE()的使用方法:
SELECT * FROM tbl_name PROCEDURE ANALYSE();
SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256);
輸出的每一列信息都會對數據表中的列的數據類型提出優化建議。以上第二個語句告訴
PROCEDURE ANALYSE()不要為那些包含的值多于16個或者256字節的ENUM類型提出建議。
如果沒有這樣的限制,輸出信息可能很長;ENUM 定義通常很難閱讀。
根據 PROCEDURE ANALYSE()函數的輸出信息,用戶可能會發現,一些表中的字段可以修
改為效率更高的數據類型。如果決定改變某個字段的類型,則需要使用 ALTER TABLE 語句。
下面分析一下表 duck_cust 的數據類型是否需要優化。
(1)首先創建測試表 duck_cust,duck_cust 表中記錄了客戶的一些基本信息:
drop table duck_cust;
CREATE TABLE duck_cust(
cust_num MEDIUMINT AUTO_INCREMENT, --客戶編號
cust_title TINYINT, --客戶標題號
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)然后生成一些測試數據:
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');
這時,查看一下表結構:
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()函數確定要優化的列:
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 ***************************
從結果中,可以看到 test.duck_cust.cust_num 列的 Min_length、Max_length、
Avg_value_or_avg_length,根據這些統計值,可以對列進行優化,例如,插入的數據最大長度
和最小長度都是 1,所以,可以優化字段 cust_num 為 mediumint(2);同時,上面的結果也
給出了優化建議“Optimal_fieldtype: ENUM('1','2','3','4','5','6') NOT NULL”。
看到這個建議讀者可能會覺得很奇怪,怎么給出了枚舉類型?而不是我們預期的整型。
因為這時分析的測試表記錄數太少,使得 cust_name 的唯一值太少,因此函數覺得用枚舉類
型會更合理。如果是對一個大表進行分析,提出的建議會更準確。
根據給出的統計信息和優化建議,可以使用如下語句進行字段類型的更改:
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 通過拆分提高表的訪問效率 這里所說的“拆分”,是指對數據表進行拆分。有 兩種拆分方法。 (1)?第一種方法是垂直拆分,即把主碼和一些列放到一個表,然后把主碼和另外的列放 到另一個表中。 如果一個表中某些列常用,而另外一些列不常用,則可以采用垂直拆分,另外垂直 拆分可以使得數據行變小,一個數據頁就能存放更多的數據,在查詢時就會減少 I/O 次 數。其缺點是需要管理冗余列,查詢所有數據需要聯合(JOIN)操作。 (2)?第二種方法是水平拆分,即根據一行或多行數據的值把數據行放到兩個獨立的表中。 水平拆分通常在以下幾種情況下使用: (a) 表很大,分割后可以降低在查詢時需要讀的數據和索引的頁數,同時也降低了 索引的層數,提高查詢速度。 (b) 表中的數據本來就有獨立性,例如,表中分別記錄各個地區的數據或不同時期 的數據,特別是有些數據常用,而另外一些數據不常用。 ? (c) 需要把數據存放到多個介質上。 例如,移動電話的賬單表就可以分成兩個表或多個表。最近 3 個月的賬單數據存在一 個表中,3 個月前的歷史賬單存放在另外一個表中,超過 1 年的歷史賬單可以存儲到 單獨的存儲介質上,這種拆分是最常使用的水平拆分方法。 水平拆分會給應用增加復雜度,它通常在查詢時需要多個表名,查詢所有數據需 要 UNION 操作。在許多數據庫應用中,這種復雜性會超過它帶來的優點,因為只要 索引關鍵字不大,則在索引用于查詢時,表中增加 2 至 3 倍數據量,查詢時也就增加 讀一個索引層的磁盤次數,所以水平拆分要考慮數據量的增長速度,根據實際情況決 定是否需要對表進行水平拆分。 3 使用中間表提高統計查詢速度 對于數據量較大的表,在其上進行統計查詢通常會效率很低,并且還要考慮統計查詢是 否會對在線的應用產生負面影響。通常在這種情況下,使用中間表可以提高統計查詢的效率, 下面通過對 session 表的統計來介紹中間表的使用: (1)session 表記錄了客戶每天的消費記錄,表結構如下: CREATE TABLE session ( cust_id varchar(10) , --客戶編號 cust_amount DECIMAL(16,2), --客戶消費金額 cust_date DATE, --客戶消費時間 cust_ip varchar(20) –客戶 IP 地址 ) (2)由于每天都會產生大量的客戶消費記錄,所以 session 表的數據量很大,現在業務部門有 一具體的需求:希望了解最近一周客戶的消費總金額和近一周每天不同時段用戶的消費總金 額。針對這一需求我們通過 2 種方法來得出業務部門想要的結果。 方法 1:在 session 表上直接進行統計,得出想要的結果。 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:創建中間表 tmp_session,表結構和源表結構完全相同。 CREATE TABLE tmp_session ( cust_id varchar(10) , --客戶編號 cust_amount DECIMAL(16,2), --客戶消費金額 cust_date DATE, --客戶消費時間 cust_ip varchar(20) –客戶 IP 地址 ) ; 轉移要統計的數據到中間表,然后在中間表上進行統計,得出想要的結果。 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 種實現方法上看,在中間表中做統計花費的時間很少(這里不計算轉移 數據花費的時間),另外,針對業務部門想了解“近一周每天不同時段用戶的消費總金 額”這一需求,在中間表上給出統計結果更為合適,原因是源數據表(session 表) cust_date 字段沒有索引并且源表的數據量較大,所以在按時間進行分時段統計時效率 很低,這時可以在中間表上對 cust_date 字段創建單獨的索引來提高統計查詢的速度。 中間表在統計查詢中經常會用到,其優點如下: ? 中間表復制源表部分數據,并且與源表相“隔離”,在中間表上做統計查詢不 會對在線應用產生負面影響。 ? 中間表上可以靈活的添加索引或增加臨時用的新字段,從而達到提高統計查詢 效率和輔助統計查詢作用。
總結
以上是生活随笔為你收集整理的mysql优化数据库对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Springboot实现手机短信服务
- 下一篇: 攻城略地mysql充值_攻城掠地充值有巨