MySQL大表優化
SQL語句優化
一、DDL(Data Definition Language 數據定義語言)
用于操作對象和對象的屬性,這種對象包括數據庫本身,以及數據庫對象,像:表、視圖等等,DDL 對這些對象和屬性的管理和定義具體表現在 create、drop 和 alter 上。特別注意:DDL 操作的“對象”的概念,”對象“包括對象及對象的屬性,而且對象最小也比記錄大個層次。以表舉例:create 創建數據表,alter 可以更改該表的字段,drop 可以刪除這個表。由此得知,DDL 不涉及具體的數據。所有的 DDL 均將被隱式提交,無法 ROLLBACK。
1??DDL的主要操作
- 【create】
可以創建數據庫和數據庫的一些對象。 - 【drop】
- drop 是 DDL,會隱式提交,所以不能回滾,不會觸發觸發器。
- drop 刪除表結構及所有數據,并將表所占用的空間全部釋放。
- drop 將刪除表的結構,所依賴的約束,觸發器,索引以及數據表的權限等,依賴于該表的存儲過程/函數將保留,但是變為 invalid 狀態。
- 【truncate】
truncate table tabname
一次性地從表中刪除所有的數據頁并不把單獨的刪除操作記錄記入日志保存,刪除行是不能恢復的。并且在刪除的過程中不會激活與表有關的刪除觸發器。執行速度快。
- truncate 是 DDL,會隱式提交,所以不能回滾,不會觸發觸發器。
- truncate 會刪除表中所有記錄,并且將重新設置高水線和所有的索引,缺省情況下將空間釋放到 minextents 個 extent,除非使用 reuse storage。不會記錄日志,所以執行速度很快,但不能通過 rollback 撤消操作(如果一不小心把一個表 truncate 掉,也是可以恢復的,只是不能通過 rollback 來恢復)。
- 對于外鍵(foreign key)約束引用的表,不能使用 truncate table,而應使用不帶 where 子句的 delete 語句。
- truncate table不能用于參與了索引視圖的表。
- 【alter】
修改數據表定義及屬性。
2??DDL的操作對象(表)
表的概念
表的創建就是用來存放數據用的,由于存放的數據的不同,所以需要定義些數據類型,以方便管理。表的屬性
【主鍵屬性】
主鍵就是主鍵約束,主鍵的起名偏向于虛的(就是描述這件事),主鍵約束起名偏向于實得(就是描述操作的實施),描述的都是同一件事,主鍵約束就是表中的一個屬性。在一個表中最多可以有一個主鍵,一個主鍵可以定義在一個或多個字段。主鍵使一個或多個字段的值必須唯一且不為空,這樣做可以通過該字段或該組字段中的值唯一的代表一條記錄。
【唯一屬性】
一個表中只能有一個主鍵屬性,為了方表用戶,提出唯一約束。唯一約束可以定義在一個或多個字段上。唯一約束使該字段或該組字段中的值唯一,可以為空,但是不能重復。
【外鍵屬性】
又叫外鍵、外鍵約束,跟主鍵和主鍵約束的關系是一樣的。外鍵約束針對的兩個表,如果表A的主關鍵字是表B中的字段,則該字段稱為表B的外鍵,表A稱為主表,表B稱為從表。但要注意,必須要系統知道是這種關系。
【核查、Null 和缺省屬性】
核查屬性又叫核查約束,Null 屬性又叫 Null 約束,缺省屬性又叫缺省約束。這些名稱是描述一件事,描述一種情況,這件事或這張情況。當然可以人為的那樣特意做(輸入數據時注意就行),但本意是實現自動化,也就是讓計算機做這件事。
二、DML(Data Manipulation Language 數據操控語言)
用于操作數據庫對象中包含的數據,也就是說操作的單位是記錄。
1??DML的主要語句操作
- 【insert】
向數據表張插入一條記錄。 - 【delete】
刪除數據表中的一條或多條記錄,也可以刪除數據表中的所有記錄。但是,它的操作對象仍是記錄。
delete 是DML,執行時,每次從表中刪除一行,并且同時將該行的刪除操作記錄在 redo 和 undo 表空間中以便進行回滾(rollback)和重做操作,但要注意表空間要足夠大,需要手動提交(commit)操作才能生效,可以通過 rollback 撤消操作。
delete 可根據條件刪除表中滿足條件的數據,如果不指定 where 子句,那么刪除表中所有記錄。
delete 不影響表所占用的 extent,高水線(high watermark)保持原位置不變。
- 【update】
用于修改已存在表中的記錄的內容。
2??DML的操作對象——記錄
三、DCL(Data Control Language 數據控制語句)
DCL的操作是數據庫對象的權限,這些操作的確定使數據更加的安全。
1??DCL的主要語句操作
- 【grant】
允許對象的創建者給某用戶或某組或所有用戶(PUBLIC)某些特定的權限。 - 【revoke】
可以廢除某用戶或某組或所有用戶訪問權限
2??DCL的操作對象(用戶):
此時的用戶指的是數據庫用戶。
四、MySQL 相關基本語句
1??插入記錄
insert into tab (field1,field2) values (value1,value2);
2??刪除記錄
delete from tab where conditions;
3??更新記錄
update tab set field1=value1,field2=value2 where conditions;
MySQL 給一個字段遞增賦值:
①首先設置一個變量,初始值為0:set @r:=0;
②然后更新表中對應的ID列:update tab set id=(@r:=@r+1)
③如果是插入,那就找一個記錄多的表 t1:
set @r:=0;
insert into t select @r:=@r+1 from t1 limit 0, 2000
4??查詢數據
select * from tab where conditions order by field desc;(精準查詢)
asc升序【默認】 / desc降序
select * from tab where field like '%value%'(模糊查詢)
order by id desc,time desc
-----id 降序排列優先;id 一樣的話,再按 time 降序排列(前提是滿足 id 降序排列)。后面再加第三列的話,同理。
中文排序異常解決(第十點)
5??提交數據/回滾數據
commit;//提交數據
rollback;//回滾數據
6??總數
select count(*) from tab;
7??求和/求平均值
select sum(field) as sumvalue from tab;//求和
select avg(field) as avgvalue from tab;//求平均值
8??最大/最小
select max(field) as maxvalue from tab;//最大
select min(field) as minvalue from tab;//最小
9??分組
grounp by:一張表,一旦分組完成后,查詢只能得到組相關的信息。
??between限制查詢數據范圍時包括了邊界值。
select * from tab where time between time1 and time2;
select a,b,c from tab where a not between num1 and num2;
1??1??in的用法
select * from tab where a [not] in ('值1','值2','值3','值4')
1??2??兩張關聯表,刪除主表中已經在副表中沒有的信息
delete from tab1 where not exists
(select * from tab2 where tab1.field1=tab2.field2)
1??3??四表聯查
select * from a
left inner join b on a.a=b.b
right inner join c on a.a=c.c
inner join d on a.a=d.d
where conditions
1??4??查詢相同條目并記錄重復次數(大于2)
select a,count(a) from tab group by a having count(*) > 2
1??5??創建數據庫/刪除數據庫
create database database_name;//創建數據庫
drop database database_name;## 刪除數據庫
1??6??創建新表/刪除表
## 創建新表
create table dept(
id int(11) not null auto_increment,
name varchar(255) default null,
primary key(dept_id)
);
## 刪除表
drop table tab;
1??7??根據已有的表創建新表
create table ntab like otab;(使用舊表B創建新表A) (MySQL)
備注:此種方式在將表B復制到A時候,會將表B完整的字段結構和索引復制到表A中來。但不會復制數據。
create table ntab as select col1,col2... from otab definition only;
備注:此種方式只會將B表的字段結構復制到表A中來,但不會復制表B中的索引到表A中來。這種方式比較靈活可以在復制原來表結構的同時指定要復制哪些字段,并且自身復制表也可以根據需要增加字段結構。
1??8??新增表的別名
comment on tab col is '測試';
1??9??更改表名
alter table tab_oldName rename to tab_newName;
2??0??增加一個列
alter table tab add column_name type;
alter table 表名 ADD 字段名稱 字段類型(字段長短-選填)
NOT NULL[是否為null] default 0 comment '字段備注';
2??1??添加主鍵/刪除主鍵
alter table tab add primary key(col);//添加主鍵
alter table tab drop primary key(col);//刪除主鍵
一個數據表只可以有一個主鍵,所以不存在刪除某一列的主鍵。
2??2??創建索引/刪除索引索引不可以更改,想更改必須刪除重新建。
//創建索引
create [unique] index idxname on tab(col...);
//刪除索引
drop index idxname;
drop index idxname on table;
2??3??查看某個表的索引
show index from table_name
2??4??創建視圖/刪除視圖
//創建視圖
create view viewname as select statement;
//刪除視圖
drop view viewname;
五、pro
select * from dba_blockers;
查詢鎖
select * from dba_waiters;
查詢被阻塞的會話
select column_name from tab_old intersect select column_name from tab_new;
顯示兩表的相同數據
select @@version; 或 select version();
查看數據庫版本
select database();
查看當前數據庫
select user();
查看當前用戶
show tables;
查看所有表
show columns from table;
查看表中的列的基本信息
desc table; 或 describe table;
表名后加字段名,查看該字段基本信息
select CHARACTER_LENGTH(col) from table;
查詢該字段值的長度
六、Oracle 相關基本語句
1??查詢表名
select table_name,tablespace_name,temporary
from user_tables [where table_name=upper('表名')];
- table_name:表名(varchar2(30))
- tablespace_name:存儲表名的表空間(varchar2(30))
- temporary:是否為臨時表(varchar2(1))
2??查詢表列名
select column_name,data_type,data_length,data_precision,data_scale
from user_tab_columns [where table_name=upper('表名')];
select table_name,column_name
from user_tab_columns
where column_name like '%xxx%' and table_name like '%xxx%';
- column_name:列名(varchar2(30))
- data_type:列的數據類型(varchar2(106))
- data_length:列的長度(number)
另外,也可以通過 all_tab_columns來獲取相關表的數據。
select * from all_tab_columns [where table_name='表名'];
3??根據表名,查詢表的索引
select * from user_indexes [where table_name=upper('表名')];
select* from all_indexes where table_name=upper('表名');
select * from user_ind_columns where table_name=upper('表名');
4??根據索引名,查詢表的索引字段
select * from user_ind_columns [where index_name=('索引名')];
5??根據索引名,查詢創建索引的語句
select dbms_metadata.get_ddl('INDEX','索引名', ['用戶名']) from dual ;
-- ['用戶名']可省,默認為登錄用戶。
6??查詢數據庫版本
select * from v$version;
select * from product_component_version
where SUBSTR(PRODUCT,1,6)='Oracle';
select version from v$instance;
七、drop、truncate 和 delete 的區別
1??truncate 和 delete 只刪除數據, drop 則刪除整個表(結構和數據)。
2???truncate 只能對 table。delete 可以是 table 和 view。
3??一般速度上,drop > truncate > delete。delete 操作不會減少表或索引所占用的空間,truncate 會將該表和索引所占用的空間會恢復到初始大小,drop 將表所占用的空間全釋放掉。
4??truncate 與不帶 where 的 delete :只刪除數據,而不刪除表的結構(定義)。drop 語句將刪除表的結構被依賴的約束(constrain)、觸發器(trigger)、索引(index),依賴于該表的存儲過程/函數將被保留,但其狀態會變為:invalid。
5??delete 執行的過程是每次從表中刪除一行,同時將該刪除操作作為事務記錄在日志中保存以便進行回滾操作。該操作是 DML 會被放到 rollback segment 中,事務提交后才生效。如果有相應的 tigger,執行的時候將被觸發。
truncate table 一次性刪除表所有的數據并不記錄日志,刪除行不可恢復。并且在刪除的過程中不會激活與表有關的刪除觸發器。執行速度快。truncate、drop 是 DDL 操作立即生效,原數據不放到 rollback segment 中,不能回滾。
6??truncate table tabname
速度快,效率高。truncate table 在功能上與不帶 WHERE 子句的 delete 語句相同:二者均刪除表中的全部行。但 truncate table 比 delete 速度快,且使用的系統和事務日志資源少。delete 語句每次刪除一行,并在事務日志中為所刪除的每行記錄一項。truncate table 通過釋放存儲表數據所用的數據頁來刪除數據,并且只在事務日志中記錄頁的釋放。
7??truncate table 刪除表中的所有行,但表結構及其列、約束、索引等保持不變。新行標識所用的計數值重置為該列的種子。如果想保留標識計數值,請改用 delete。如果要刪除表定義及其數據,請使用 drop table 語句。
8??對于由 foreign key 約束引用的表,不能使用 truncate table,而應使用不帶 where 子句的 delete 語句。由于 truncate table 不記錄在日志中,所以它不能激活觸發器。
9??總結
在速度上,一般來說,drop> truncate > delete。
在使用 drop 和 truncate 時一定要注意,雖然可以恢復,但為了減少麻煩,還是要慎重。
如果想刪除部分數據用 delete,注意帶上 where 子句,回滾段要足夠大;如果想刪除表,當然用 drop;如果想保留表而將所有數據刪除,如果和事務無關,用 truncate 即可;如果和事務有關,或者想觸發 trigger,還是用 delete;如果是整理表內部的碎片,可以用 truncate 跟上 reuse stroage,再重新導入/插入數據。
八、MySQL 和 Oracle 的區別
MySQL 和 Oracle 都是流行的關系數據庫管理系統(RDBMS),在世界各地廣泛使用。大多數數據庫以類似的方式工作。兩個數據庫的特性是不同的。
1??本質的區別
- Oracle 數據庫是一個對象關系數據庫管理系統(ORDBMS)。它通常被成為 OracleRDBMS 或簡稱為 Oracle,是一個收費的數據庫。
- MySQL 是一個開源的關系數據庫管理系統(RDBMS)。它是世界上使用最多的 RDBMS(Relational Database Management System,關系數據庫管理系統),作為服務器運行,提供多個數據庫的多用戶訪問。它是一個免費的數據庫。
2??數據庫安全性
- MySQL 使用三個參數來驗證用戶,即用戶名、密碼和位置。
- Oracle 使用了許多安全功能,如用戶名,密碼,配置文件,本地身份驗證,外部身份驗證,高級安全增強功能等。
3??SQL語法的區別
Oracle 的 SQL 語法與 MySQL 有很大不同。Oracle 為稱為 PL/SQL 的編程語言提供了更大的靈活性。Oracle 的 SQL*Plus 工具提供了比 MySQL 更多的命令,用于生成報表輸出和變量定義。
4??存儲上的區別
與 Oracle 相比,MySQL 沒有表空間、角色管理、快照、同義詞和包以及自動存儲管理。
5??對象名稱的區別
雖然某些模式對象名稱在 Oracle 和 MySQL 中都不區分大小寫,例如列、存儲過程和索引等。但在某些情況下,兩個數據庫之間的區別大小寫是不同的:
- Oracle 對所有對象名稱都不區分大小寫。
- 某些 MySQL 對象名稱(如數據庫和表)區分大小寫(取決于底層操作系統)。
6??運行程序和外部程序支持
- Oracle 數據庫支持從數據庫內部編寫,編譯和執行的幾種編程語言。此外,為了傳輸數據,Oracle 數據庫使用 XML。
- MySQL 不支持在系統內執行其他語言,也不支持 XML。
7??MySQL和Oracle的字符數據類型比較
兩個數據庫中支持的字符類型存在一些差異。
- 對于字符類型,MySQL 具有 CHAR 和 VARCHAR,最大長度允許為65535字節(CHAR 最多可以為255字節,VARCHAR 為65535字節)。
- 而 Oracle 支持四種字符類型,即 CHAR、NCHAR、VARCHAR2和NVARCHAR2。所有四種字符類型都需要至少1個字節長;CHAR 和 NCAHR 最大可以是2000個字節,VARCHAR2 和 NVARCHAR2 的最大限制是4000個字節。可能會在最新版本中進行擴展。
8??MySQL 和 Oracle 的額外功能比較
- MySQL 數據庫不支持其服務器上的任何功能,如 Audit Vault。
- Oracle支持其數據庫服務器上的幾個擴展和程序,例如 Active Data Guard,Audit Vault,Partitioning 和 Data Mining 等。
9??臨時表的區別:Oracle 和 MySQL 以不同方式處理臨時表。
- 在 MySQL 中,臨時表是僅對當前用戶會話可見的數據庫對象,并且一旦會話結束,這些表將自動刪除。
- Oracle 中臨時表的定義與 MySQL 略有不同,因為臨時表一旦創建就會存在,直到它們被顯式刪除,并且對具有適當權限的所有會話都可見。但是,臨時表中的數據僅對數據插入表中的用戶會話可見,并且數據可能在事務或用戶會話期間持續存在。
??MySQL 和 Oracle 中的備份類型
- Oracle 提供不同類型的備份工具,如冷備份,熱備份,導出,導入,數據泵。Oracle 提供了最流行的稱為 RecoveryManager(RMAN)的備份實用程序,可以使用極少的命令或存儲腳本自動化備份調度和恢復數據庫。
- MySQL 有 mysqldump 和 mysqlhotcopy 備份工具。在 MySQL 中沒有像 RMAN 這樣的實用程序。
1??1??Oracle 和 MySQL 的數據庫管理
在數據庫管理部分,Oracle DBA 比 MySQL DBA 更有收益。與 MySQL 相比,Oracle DBA 有很多可用的范圍。