数据库版本Oracle11gR2SQLgt; select * from v$version where rownum=1;BANNEROracle Database 11g Enterprise Edition Release
数据库版本Oracle11gR2
SQL> select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
创建手动管理的表空间,blockssize 8k
SQL> create tablespace test datafile
'/u01/app/oracle/oradata/ROBINSON/datafile/test.dbf' size 50m autoextend on maxsize 200m
uniform size 1m segment space management manual blocksize 8k; 2 3
Tablespace created.
创建测试用户test,默认表空间 test
SQL> create user test identified by oracle default tablespace test;
User created.
为了简便,授权DBA给test
SQL> grant dba to test;
Grant succeeded.
创建测试表test
SQL> create table test as select * from dba_objects where 1=0 ;
Table created.
设置pctfree 99
SQL> alter table test pctfree 99 pctused 1;
Table altered.
SQL> insert into test select * from dba_objects where rownum
1 row created.
确保一行一个block
SQL> alter table test minimize records_per_block;
Table altered.
SQL> insert into test select * from dba_objects where rownum
999 rows created.
SQL> commit;
Commit complete.
收集表统计信息
SQL> BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'TEST',
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns size 1',
degree => DBMS_STATS.AUTO_DEGREE,
cascade=>TRUE
);
END;
/ 2 3 4 5 6 7 8 9 10
PL/SQL procedure successfully completed.
SQL> select owner,blocks from dba_tables where owner='TEST' and table_name='TEST';
OWNER BLOCKS
------------------------------ ----------
TEST 1000
SQL> show parameter db_file_multiblock_read_count
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer 16
全表扫描的成本等于220
SQL> select count(*) from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1950795681
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 220 (0)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST | 1000 | 220 (0)| 00:00:03 |
-------------------------------------------------------------------
成本的计算方式如下:
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
CPUCycles / cpuspeed
) / sreadtime
#SRds - number of single block reads
#MRds - number of multi block reads
#CPUCyles - number of CPU cycles
sreadtim - single block read time
mreadtim - multi block read time
cpuspeed - CPU cycles per second
注意:如果没有收集过系统统计信息,那么Oracle采用非工作量统计, 如果收集了,,Oracle采用工作量统计的计算方法
SQL> select pname, pval1 from sys.aux_stats$ where sname='SYSSTATS_MAIN';
PNAME PVAL1
------------------------------ ----------
CPUSPEED
CPUSPEEDNW 2696.05568
IOSEEKTIM 10
IOTFRSPEED 4096
MAXTHR
MBRC
MREADTIM
SLAVETHR
SREADTIM
9 rows selected.
我这里因为MBRC 为0,所以CBO采用了非工作量(noworkload)来计算成本
#SRds=0,因为是全表扫描,单块读为0
#MRds=表的块数/多块读参数=1000/16
mreadtim=ioseektim+db_file_multiblock_count*db_block_size/iotftspeed
SQL> select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
2 (select value
from v$parameter
where name = 'db_file_multiblock_read_count') *
(select value from v$parameter where name = 'db_block_size') /
(select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "mreadtim"
3 4 5 6 7 from dual;
mreadtim
----------
42
sreadtim=ioseektim+db_block_size/iotfrspeed
SQL> select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
(select value from v$parameter where name = 'db_block_size') /
(select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "sreadtim"
from dual; 2 3 4
sreadtim
----------
12
CPUCycles 等于 PLAN_TABLE里面的CPU_COST
SQL> explain plan for select count(*) from test;
Explained.
SQL> select cpu_cost from plan_table;
CPU_COST
----------
7271440
cpuspeed 等于 CPUSPEEDNW= 2696.05568
那么COST=1000/16*42/12+7271440/2696.05568/12/1000
SQL> select ceil(1000/16*42/12+7271440/2696.05568/12/1000) from dual;
CEIL(1000/16*42/12+7271440/2696.05568/12/1000)
----------------------------------------------
219
手工计算出来的COST用四舍五入等于219,和我们看到的220有差别, 这是由于隐含参数_tablescan_cost_plus_one参数造成的
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
FROM x$ksppi x, x$ksppcv y
WHERE x.inst_id = USERENV ('Instance')
AND y.inst_id = USERENV ('Instance')
AND x.indx = y.indx
AND x.ksppinm LIKE '%_table_scan_cost_plus_one%'
/ 2 3 4 5 6 7
NAME VALUE DESCRIB
------------------------------ ---------- ------------------------------
_table_scan_cost_plus_one TRUE bump estimated full table scan
and index ffs cost by one
根据该参数的描述,在table full scan和index fast full scan的时候会将cost+1
那么我把改参数禁止了试一试
SQL> alter session set "_table_scan_cost_plus_one"=false;
Session altered.
SQL> set autot trace
SQL> select count(*) from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1950795681
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 219 (0)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST | 1000 | 219 (0)| 00:00:03 |
-------------------------------------------------------------------
这次得到的Cost等于219,与计算值正好匹配,现在更改db_file_multiblock_read_count参数
SQL> alter session set db_file_multiblock_read_count=32;
Session altered.
这个时候 sreadtim=12
SQL> select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
(select value from v$parameter where name = 'db_block_size') /
(select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "sreadtim"
from dual; 2 3 4
sreadtim
----------
12
mreadtim=74
SQL> select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
(select value
2 3 from v$parameter
4 where name = 'db_file_multiblock_read_count') *
5 (select value from v$parameter where name = 'db_block_size') /
6 (select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "mreadtim"
7 from dual;
mreadtim
----------
74
那么cost等于
SQL> select ceil(1000/32*74/12+7271440/2696.05568/12/1000) from dual;
CEIL(1000/32*74/12+7271440/2696.05568/12/1000)
----------------------------------------------
193
SQL> set autot trace
SQL> select count(*) from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1950795681
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 193 (0)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST | 1000 | 193 (0)| 00:00:03 |
-------------------------------------------------------------------
与计算的Cost相匹配,从实验种可以得出,在11gR2中,全表扫描计算Cost的方式依然和9i/10g一样,没有变化。
相关链接

本文探討了Docker中的優化MySQL內存使用量。 它討論了監視技術(Docker統計,性能架構,外部工具)和配置策略。 其中包括Docker內存限制,交換和cgroups

本文介紹了MySQL的“無法打開共享庫”錯誤。 該問題源於MySQL無法找到必要的共享庫(.SO/.DLL文件)。解決方案涉及通過系統軟件包M驗證庫安裝

本文討論了使用MySQL的Alter Table語句修改表,包括添加/刪除列,重命名表/列以及更改列數據類型。

本文比較使用/不使用PhpMyAdmin的Podman容器直接在Linux上安裝MySQL。 它詳細介紹了每種方法的安裝步驟,強調了Podman在孤立,可移植性和可重複性方面的優勢,還

本文提供了SQLite的全面概述,SQLite是一個獨立的,無服務器的關係數據庫。 它詳細介紹了SQLite的優勢(簡單,可移植性,易用性)和缺點(並發限制,可伸縮性挑戰)。 c

本指南展示了使用自製在MacOS上安裝和管理多個MySQL版本。 它強調使用自製裝置隔離安裝,以防止衝突。 本文詳細詳細介紹了安裝,起始/停止服務和最佳PRA

文章討論了為MySQL配置SSL/TLS加密,包括證書生成和驗證。主要問題是使用自簽名證書的安全含義。[角色計數:159]

文章討論了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比較了它們對初學者和高級用戶的功能和適合性。[159個字符]


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver CS6
視覺化網頁開發工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中