MySql拓展

目錄

 

1  分區及分表

http://blog.csdn.net/yongchao940/article/details/55266603

1.1 橫向分區與縱向分區

1.2 分區的內在涵義

1.3 分區的常見語句及注意事項

1.4  分區和索引

1.5  MySQL分表

2 binlog

2.1 binlog

2.2 binlog開啓

2.3 binlog試用

2.4 實踐

3 鎖

4 基本操作

4.1 修改字段列排序

4.2 replace into與 insert into ... on duplicate key update

5 存儲

6. 問題


1  分區及分表

http://blog.csdn.net/yongchao940/article/details/55266603

1.1 橫向分區與縱向分區

橫向:記錄分

縱向:字段分

1.2 分區的內在涵義

1.2.1 分區意義

首先MYISAM、InnoDB都是支持分區的。

1. 表非常大以至於無法全部都放到內存,或者只在表的最後部分有熱點數據,其他均爲歷史數據

2. 分區表數據更容易維護(可獨立對分區進行優化、檢查、修復及批量刪除大數據可以採用drop分區的形式等)

3. 分區表的數據可以分佈在不同的物理設備上,從而高效地利用多個硬件設備

4. 分區表可以避免某些特殊的瓶頸(ps: InnoDB的單個索引的互斥訪問、ext3文件系統的inode鎖競爭等) 5、可以備份和恢復獨立的分區,非常適用於大數據集的場景、

5. 進行大數據搜索的時候可以進行並行處理

6. 跨多個磁盤分散數據查詢,來獲得更大的查詢吞吐量。

1.2.2 分區物理存儲

對應MySQL三個文件的具體情況.

分區在邏輯上是一個表,但是實際上卻可以由多個物理分區組成。在執行查詢的時候,和優化器會根據分區定義過濾出我們需要數據的分區,無須全表掃描。刪除數據的時候同樣的道理,效率也是非常的高。

1.3 分區的常見語句及注意事項

1.3.1 注意事項  

http://lobert.iteye.com/blog/1955841

http://www.simlinux.com/2014/08/19/mysql-partitions.html

範圍分區添加分區只能在最大值後面追加分區

 比如 現在已經有了如下分區

 

 

p0

5

p1

10

p2

15

1.  分區值必須是嚴格遞增的。如上圖,那麼插入 alter table orders_range add partition(partition p3 values less than (12));是無法插入成功的。

因此如果我們在程序中有 alter table orders_range add partition(partition p3 values less than MAXVALUE);

2. 此時需要添加分區,需要先刪除max對應的分區,然後再添加我們需要的分區

3. 如果我們最後一個分區是[10,15),那麼我們插入的值>=15都是插入不進去的,會報錯。

4. 所有分區的engine必須一樣

5.  分區間隔必須是int,分區名稱不能以數字開頭  這個導致我們ETL中 preload刪除分區無法形成這種語法。只能借用delete刪除數據

6. less than 表示分割區間是 [ )形式

7. 如果表上有主鍵或唯一索引列,range方式分區必須加入 https://www.zhihu.com/question/21738216  

每個分區值上都有獨立的索引。 一般原則就是分區列必作爲索引。

分區表的索引只是在各個底層表各自加上一個完全相同的索引。之於存儲引擎,分區表的底層表與普通表沒有區別。

 

8. null對分區主鍵的影響?

 

9 MySQL中插入換行

直接插入\n 或者通過char(13)的形式,

一般比如 concat_ws('\n',a,b,c)或者 concat_ws(char(13),a,b,c)

 

 

1.3.2 分區操作

1 查看分區

代碼塊

Plain Text

SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'table_name';

2 添加分區

代碼塊

Plain Text

alter table orders_range add partition(partition p5 values less than (25));alter table orders_range add partition(partition p5 values less than MAXVALUE);

note:在create語句中沒有進行分區的相關定義,也可以可以添加分區的。

代碼塊

Plain Text

*可以對現有表進行分區,並且會按規則自動的將表中的數據分配相應的分區 
中,這樣就比較好了,可以省去很多事情,看下面的操作*/  
mysql> alter table aa partition by RANGE(id)  
 -> (PARTITION p1 VALUES less than (1),  
 -> PARTITION p2 VALUES less than (5),  
 -> PARTITION p3 VALUES less than MAXVALUE);  
Query OK, 15 rows affected (0.21 sec)   //對15數據進行分區  
Records: 15  Duplicates: 0  Warnings: 0  

3 刪除分區

note: 批量刪除分區

alter table xx drop drop partition  p17177,p17178;

這種帶有數字的直接用Excel拖動生成就行了

note:

多表記錄級聯刪除,在一些orm中直接配置級聯就可以刪除,單純的數據庫而言也是可以的

DELETE FROM tablename [WHERE CONDITION]

delete from emp where ename='dony';

一次刪除多個表的數據,語法如下:
delete t1,t2 from table_name as t1 left join table2_name as t2 on t1.id=t2.id where table_name.id=25

4 其他操作

1.4  分區和索引

從本質來說就是兩個東西,沒有什麼本質的關係

但是從效果來說,都能加快查詢的速度。但是在修改表(包括但不限於刪除)層面上,分區的效率優勢就體現出來了。尤其是在表非常大的情況下。

##

1.5  MySQL分表

1.5.1 分表和分區的區別

http://blog.51yip.com/mysql/949.html

1.5.2 索引

1 首先連接字段,在連接的兩個表中的字段類型一致比不一致效率高一點,但是不明顯,最起碼在200w數據量的情況下是不明顯的。 note: in(23,225)這種情況就會走range索引

2  count(*)比sum(*)的效率高一點,但是在200w+數據量的情況下只有0.0xs的優勢,也是很不明顯

3  複合主鍵在索引層面,就相當於聯合索引,也是符合在最左前綴原則

4 索引失效情況

### 從左到右,遇到範圍查詢即索引失效(in不包括在內)。

範圍查詢其實可以做進一步的細化區分,in更加細化的描述應該是多值精確匹配, between則是範圍查詢。

### 隱式類型轉換

http://tomhjx.github.io/2016/01/03/MYSQL%E7%B4%A2%E5%BC%95%E5%A4%B1%E6%95%88%E7%9A%84%E5%90%84%E7%A7%8D%E6%83%85%E5%BD%A2%E6%80%BB%E7%BB%93/

 

mysql隱士類型轉換坑較多,不要使用隱士類型轉換。

note:隱式類型轉換還有一個查詢匹配的大坑

當字段是string類型的時候,查詢條件爲 int 0的時候,會匹配上字段中以字符開頭的記錄

 

關於隱式轉換的規則,

  • 當查詢字段是INT類型,如果查詢條件爲CHAR,將查詢條件轉換爲INT,如果是字符串前導都是數字將會進行截取,如果不是轉換爲0。

  • 當查詢字段是CHAR類型,如果查詢條件爲INT,將查詢字段爲換爲INT再進行比較,可能會造成全表掃描。示例2的name字段爲CHAR類型,第一句查詢轉換爲INT時都等於0,所以全部匹配了;第二句查詢同爲CHAR類型不發生轉換,所以僅匹配值爲0的記錄。

https://blog.eood.cn/mysql_params

 

 

2 binlog

2.1 binlog

2.1.1 日誌文件

http://www.cnblogs.com/martinzhang/p/3454358.html

MySQL的二進制日誌記錄了所有的DDL和DML(除了數據查詢語句)語句,以事件形式記錄,

還包含語句所執行的消耗的時間,MySQL的二進制日誌是事務安全型的。

一般來說開啓二進制日誌大概會有1%的性能損耗(參見MySQL官方中文手冊 5.1.24版)。

二進制有兩個最重要的使用場景:

其一:MySQL Replication在Master端開啓binlog,Mster把它的二進制日誌傳遞給slaves來達到master-slave數據一致的目的。

其二:自然就是數據恢復了,通過使用mysqlbinlog工具來使恢復數據。 二進制日誌包括兩類文件:二進制日誌索引文件(文件名後綴爲.index)用於記錄所有的二進制文件,二進制日誌文件(文件名後綴爲.00000*)記錄數據庫所有的DDL和DML(除了數據查詢語句)語句事件。

2.1.2 日誌文件的擴展

當停止或重啓時,服務器會把日誌文件記入下一個日誌文件,Mysql會在重啓時生成一個新的日誌文件,文件序號遞增,此外,如果日誌文件超過max_binlog_size系統變量配置的上限時,也會生成新的日誌文件。

2.1.3 日誌文件的查看

Mysql提供了mysqlbinlog命令來查看日誌文件,如mysqlbinlog xxx-bin.001 | more。在記錄每條變更日誌的時候,日誌文件都會把當前時間給記錄下來,以便進行數據庫恢復。

2.1.4 日誌文件格式

statement格式簡單來說會記錄下執行的SQL語句,爲了保證日誌能夠恢復或者同步數據,在記錄下執行SQL的過程中,還必須記錄下上下文環境。但並不是所有的語句statement都能記錄,比如udf,沒有使用order by的limit 還有其他的一些函數和存儲過程。

但是隻記錄執行的sql語句,一般在整表修改或者alter的時候數據量會比row格式小得多

row格式會記錄下變更後的數據,但是不用記錄上下文。詳細記錄了數據修改細節。因爲如果碰到alter Table之類的語句會導致所有修改後的記錄都會被記錄(包括沒有修改的列),導致日誌數據量非常大。但是不用記錄

http://www.cnblogs.com/kevingrace/p/6065088.html

note:公司的許多庫使用的都是statement。

MySQL 5.7.7 之後默認格式是row之前使用的是statement。

 

2.2 binlog開啓

https://xcoder.in/2015/08/10/mysql-binlog-try/

http://www.cnblogs.com/EasonJim/p/7158466.html

http://blog.5ibc.net/p/122608.html

http://www.jianshu.com/p/2c8325f0d393

2.3 binlog試用

使用mysql bin目錄下的mysqlbinlog命令查看bin ./mysqlbinlog /usr/local/var/mysql/mysql-bin.000001文件,如下圖所示

 

2.4 實踐

2.4.1  max_binlog_cache_size溢出

http://liuqunying.blog.51cto.com/3984207/1751687

https://my.oschina.net/u/2485991/blog/533123

note:

max_binlog_size  一般設置爲512M或1GB,但不能超過1GB。該設置不能嚴格控制Binlog的大小,尤其是Binlog遇到比較大的事務時,爲了保證事務的完整性,不可能做切換日誌的動作,只能將該事務的所有SQL都記錄進當前日誌,直到事務結束。這種情況下回出現日誌文件大小超過設定值的情況。

binlog_cache_size 這個默認32k,公司裏有1m的也有64M的

max_binlog_cache_size  一個線程來了會按照binlog_cache_size分配cache,不夠的會用臨時文件,對於一個多事務的任務,max_binlog_cache_size會控制所有的事務總的binlog_cache_size的大小。這個值不會超過4G

show variables like '%binlog_size%'; 該命令查出來的大小的值的單位是bytes

http://blog.csdn.net/m48o8gewuc/article/details/72888092

2.4.2  在row模式下查看原生sql

公司的show variables like 'binlog_rows_query_log_events';也是打開的

http://blog.csdn.net/mchdba/article/details/52268615

2.4.3 業務庫大表在線修改表結構:

基本原理是生成中間表,複製數據,最後刪除中間表。中間的過程並不總是會複製數據,如果複製數據會導致非常耗時,極有可能會導致鎖表。

具體過程??

3 鎖

可以從引擎和讀/寫/行/表 這兩個維度來對MySQL的鎖進行分析。

redo&undo https://my.oschina.net/guol/blog/156682

4 基本操作

4.1 修改字段列排序

字段增加和修改語法(ADD/CNAHGE/MODIFY)中,都有一個可選項 first|after
column_name,這個選項可以用來修改字段在表中的位置,默認 ADD 增加的新字段是加在表的最後位置,而 CHANGE/MODIFY 默認都不會改變字段的位置。

alter table emp add birth date after ename; (alter table emp add birth date after ename,add hah after birth,add hab after hah;)可以一次增加多個列指定順序。

alter table emp modify age int(3) first; 修改字段 age,將它放在最前面

查詢順序? 不帶任何限制的查詢,

https://www.zhihu.com/question/19726583

這種有很多影響因素,一般結果會是查詢順序,但是不能依賴於這個(並不一定總是查詢順序)。

 

字段增加和修改語法(ADD/CNAHGE/MODIFY)中,都有一個可選項 first|after
column_name,這個選項可以用來修改字段在表中的位置,默認 ADD 增加的新字段是加在表的最後位置,而 CHANGE/MODIFY 默認都不會改變字段的位置。

alter table emp add birth date after ename;

alter table emp modify age int(3) first; 修改字段 age,將它放在最前面

4.2 replace into與 insert into ... on duplicate key update

replace into 相當於有重複key的情況下,會先刪除舊的記錄,然後添加一條新的記錄。沒有replace的字段則會以默認值填充。

insert into on....則是隻會修改涉及的字段,沒有涉及修改的字段還是保留原記錄的內容。

http://blog.csdn.net/mchdba/article/details/8647560

5 存儲

5.1之後就是compact格式,

  1. 減少了大約20%的空間

  2. 在某些操作下會增加CPU的佔用

  3. 在典型的應用場景下,比Redundant快
    compress用在varchar特別長,或者blob資源比較多的場景。

6. 問題

mysql不支持正則替換功能,

不支持刪除分區的非等

不支持窗口函數,但是MySQL有自己的語法來實現窗口功能。

建表語句:auto_increament=xx 表示自增數字的起點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章