【原創】自己構思2條SQL用於完成相同的功能,並比較它們的效能!
構思:想法比較簡單,有3個朋友,編寫SQL語句計算一下他們3個月工資的總和
第一種方法就是直接相加得到結果
[oracle@leonarding1 ~]$ sqlplus / as sysdba
> conn leo1/leo1
Connected.
> create table leo_wage (id number,name varchar(20),wage number,month date); 建立了 id 姓名 工資 三個欄位
Table created.
insert into leo_wage values (1,'leo',100,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (2,'leo',200,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (3,'leo',300,to_date('2012_03_01','yyyy-mm-dd'));
insert into leo_wage values (4,'sunev_yu',200,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (5,'sunev_yu',300,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (6,'sunev_yu',400,to_date('2012_03_01','yyyy-mm-dd'));
insert into leo_wage values (7,'tigerfish',300,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (8,'tigerfish',400,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (9,'tigerfish',500,to_date('2012_03_01','yyyy-mm-dd'));
> commit;
Commit complete.
> select * from leo_wage; 現在記錄已經插入了
ID NAME WAGE MONTH
---------- -------------------- ---------- ---------
1 leo 100 01-JAN-12
2 leo 200 01-FEB-12
3 leo 300 01-MAR-12
4 sunev_yu 200 01-JAN-12
5 sunev_yu 300 01-FEB-12
6 sunev_yu 400 01-MAR-12
7 tigerfish 300 01-JAN-12
8 tigerfish 400 01-FEB-12
9 tigerfish 500 01-MAR-12
> show autotrace; 檢視執行計劃,是關閉狀態
autotrace OFF
> set autotrace on; 啟動執行計劃
> show autotrace;
autotrace ON EXPLAIN STATISTICS 已經啟動
> select sum(wage) from leo_wage;
SUM(WAGE)
----------
2700
Execution Plan
----------------------------------------------------------
Plan hash value: 3461908344
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
| 2 | TABLE ACCESS FULL| LEO_WAGE | 9 | 117 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
直接彙總
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets 7次一致性讀
0 physical reads
0 redo size
527 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
show autotrace; 顯示狀態
set autotrace; 語法格式
set autotrace on explain; 即輸出sql結果又輸出執行計劃
set autotrace on statistics; 即輸出sql結果又輸出統計資訊
set autotrace traceonly; 表示不輸出sql結果,只輸出執行計劃和統計資訊
小結:看本次有7次一致性讀,感覺效率蠻好的。
第二種方法就是先計算出每個人的總和再把每個人總和求和
select sum(sum_wage) from (select name,sum(wage) sum_wage from leo_wage group by name);
> select name,sum(wage) sum_wage from leo_wage group by name; 先計算出每個人的總和
NAME SUM_WAGE
-------------------- ----------
leo 600
tigerfish 1200 還是tiger工資高,這要請吃飯a
sunev_yu 900
> select sum(sum_wage) from (select name,sum(wage) sum_wage from leo_wage group by name); 再把每個人總和求和,結果和上面的一樣
SUM(SUM_WAGE)
-------------
2700
Execution Plan
----------------------------------------------------------
Plan hash value: 1978181551
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
| 2 | VIEW | | 9 | 117 | 4 (25)| 00:00:01 |
| 3 | HASH GROUP BY | | 9 | 225 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS FULL| LEO_WAGE | 9 | 225 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------
先做分組->排序->彙總
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
15 consistent gets 15次一致性讀,一致性讀的次數代表sql的效能,一致性讀越少效能越好,這個說法前提,兩者都沒有物理讀
0 physical reads
0 redo size
531 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
小結:第二條SQL明顯比第一條SQL一致性讀次數多了一倍,效能減小了一半,那麼在實際中肯定不會這麼去寫,但這其實可以證明構造2條完全相同功能的SQL由於程式碼編寫的不夠最佳化,它們的效能可能相差甚遠。
第一種方法就是直接相加得到結果
[oracle@leonarding1 ~]$ sqlplus / as sysdba
> conn leo1/leo1
Connected.
> create table leo_wage (id number,name varchar(20),wage number,month date); 建立了 id 姓名 工資 三個欄位
Table created.
insert into leo_wage values (1,'leo',100,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (2,'leo',200,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (3,'leo',300,to_date('2012_03_01','yyyy-mm-dd'));
insert into leo_wage values (4,'sunev_yu',200,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (5,'sunev_yu',300,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (6,'sunev_yu',400,to_date('2012_03_01','yyyy-mm-dd'));
insert into leo_wage values (7,'tigerfish',300,to_date('2012_01_01','yyyy-mm-dd'));
insert into leo_wage values (8,'tigerfish',400,to_date('2012_02_01','yyyy-mm-dd'));
insert into leo_wage values (9,'tigerfish',500,to_date('2012_03_01','yyyy-mm-dd'));
> commit;
Commit complete.
> select * from leo_wage; 現在記錄已經插入了
ID NAME WAGE MONTH
---------- -------------------- ---------- ---------
1 leo 100 01-JAN-12
2 leo 200 01-FEB-12
3 leo 300 01-MAR-12
4 sunev_yu 200 01-JAN-12
5 sunev_yu 300 01-FEB-12
6 sunev_yu 400 01-MAR-12
7 tigerfish 300 01-JAN-12
8 tigerfish 400 01-FEB-12
9 tigerfish 500 01-MAR-12
> show autotrace; 檢視執行計劃,是關閉狀態
autotrace OFF
> set autotrace on; 啟動執行計劃
> show autotrace;
autotrace ON EXPLAIN STATISTICS 已經啟動
> select sum(wage) from leo_wage;
SUM(WAGE)
----------
2700
Execution Plan
----------------------------------------------------------
Plan hash value: 3461908344
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
| 2 | TABLE ACCESS FULL| LEO_WAGE | 9 | 117 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
直接彙總
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets 7次一致性讀
0 physical reads
0 redo size
527 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
show autotrace; 顯示狀態
set autotrace; 語法格式
set autotrace on explain; 即輸出sql結果又輸出執行計劃
set autotrace on statistics; 即輸出sql結果又輸出統計資訊
set autotrace traceonly; 表示不輸出sql結果,只輸出執行計劃和統計資訊
小結:看本次有7次一致性讀,感覺效率蠻好的。
第二種方法就是先計算出每個人的總和再把每個人總和求和
select sum(sum_wage) from (select name,sum(wage) sum_wage from leo_wage group by name);
> select name,sum(wage) sum_wage from leo_wage group by name; 先計算出每個人的總和
NAME SUM_WAGE
-------------------- ----------
leo 600
tigerfish 1200 還是tiger工資高,這要請吃飯a
sunev_yu 900
> select sum(sum_wage) from (select name,sum(wage) sum_wage from leo_wage group by name); 再把每個人總和求和,結果和上面的一樣
SUM(SUM_WAGE)
-------------
2700
Execution Plan
----------------------------------------------------------
Plan hash value: 1978181551
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
| 2 | VIEW | | 9 | 117 | 4 (25)| 00:00:01 |
| 3 | HASH GROUP BY | | 9 | 225 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS FULL| LEO_WAGE | 9 | 225 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------
先做分組->排序->彙總
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
15 consistent gets 15次一致性讀,一致性讀的次數代表sql的效能,一致性讀越少效能越好,這個說法前提,兩者都沒有物理讀
0 physical reads
0 redo size
531 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
小結:第二條SQL明顯比第一條SQL一致性讀次數多了一倍,效能減小了一半,那麼在實際中肯定不會這麼去寫,但這其實可以證明構造2條完全相同功能的SQL由於程式碼編寫的不夠最佳化,它們的效能可能相差甚遠。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26686207/viewspace-749677/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【原創】比較資料泵和exp/imp對相同資料匯出/匯入的效能差異
- lisp 裡的相等(相同)的比較Lisp
- JavaScript 比較相同的字元返回falseJavaScript字元False
- 【原創】比較使用sql*loader的直接載入方式和傳統載入方式的效能差異SQL
- oracle pl/sql 迴圈比較集合元素是否相同OracleSQL
- 批量插入 1 萬條資料,DB 查詢構造器和原生 SQL 效能比較SQL
- 【原創】InnoDB 和TokuDB的讀寫分析與比較
- 比較檔案是否相同,(比較MD5值)
- 比較兩個table是否相同
- 不同DBMS的SQL比較SQL
- 輸入兩個長度相同的字串,比較兩個數在相同位置的字元是否相同字串字元
- 比較兩個陣列中是否有相同的元素陣列
- Apache 的架構師們遵循的 30 條設計原則Apache架構
- SQL Server 2005 功能比較 和 限制SQLServer
- [原創]Java效能優化權威指南讀書思維導圖2Java優化
- 使用思維導圖,優雅的完成自己的程式碼
- Java Bean Copy元件的效能比較JavaBean元件
- 七種WebSocket框架的效能比較Web框架
- eAccelerator的安裝和效能比較
- DECODE和CASE的效能比較
- 【比較】Oracle不同版本中關於ALTER TABLESPACE的功能演進Oracle
- 如何分析一條sql的效能SQL
- DB2 和SQL Server自增列比較DB2SQLServer
- MySQL 中的 distinct 和 group by 的效能比較MySql
- JAVA IO效能比較Java
- 批量更新效能比較
- 雲主機的硬碟IO效能比較硬碟
- PostgreSQL、Redis與Memcached的效能比較 - CYBERTECSQLRedis
- insert的不同場景效能比較
- Linux壓縮工具的效能比較Linux
- Xml 功能在erp report中應用的模式比較XML模式
- 通過append hint來插入資料,演示它和普通插入資料的效能比較。APP
- Oracle與SQL Server在企業應用中的比較(轉)OracleSQLServer
- oracle sql日期比較:OracleSQL
- sql server日期比較SQLServer
- 前端比較實用的CSS前端CSS
- 比較兩個物件是否相同,輸出不同的屬性值(一)物件
- MyFlash工具的使用實踐及其餘binlog2sql的速度比較SQL