sort_area_size参数的一些表现

10g索引排序
本文探讨了Oracle 10g环境下创建索引时sort_area_size参数的影响。通过调整参数,观察不同设置下索引创建过程中的性能变化,包括排序统计信息、磁盘块使用情况及合并操作细节。
我们来看看该sort_area_size参数对创建索引时排序的具体影响:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

/* 测试使用版本10.2.0.4 */

SQL> archive log list;
Database log mode              No Archive Mode
Automatic archival             Disabled
Archive destination            /s01/arch
Oldest online log sequence     27
Current log sequence           34

/* 为了不受影响我们采用非归档模式 */

SQL> conn maclean/maclean
Connected.

SQL> alter session set workarea_size_policy=MANUAL;
Session altered.

/* 只有使用手动PGA管理时sort_area_size等参数才生效 */

SQL> alter session set db_file_multiblock_read_count=128;
Session altered.

/* 加大多块读参数帮助我们节约时间 */

SQL> alter session set "_sort_multiblock_read_count"=128;
Session altered.

/* 10g中sort_multiblock_read_count成为隐式参数,我们尝试手动固定它 */

SQL> set timing on;

SQL> alter session set events '10032 trace name context forever ,level 10';
Session altered.
Elapsed: 00:00:00.00

/* 在session级别设置10032事件,该事件帮助输出排序相关的统计信息*/

SQL> drop index ind_youyus;
alter session set sort_area_size=1048576;
alter session set sort_area_size=1048576;
/* 注意10g目前存在一个bug,sort_area_size需要手动设置2次方能生效,否则无效! */

create index ind_youyus on youyus(t1,t2) nologging;
Index dropped.

Elapsed: 00:00:00.07
SQL>
Session altered.

Elapsed: 00:00:00.00
SQL>
Session altered.

Elapsed: 00:00:00.00
SQL>
Index created.

Elapsed: 00:00:35.70

/* 以下为对应创建索引排序的10032 trace * /

---- Sort Parameters ------------------------------
sort_area_size                    1048576
sort_area_retained_size           1048576
sort_multiblock_read_count        29
max intermediate merge width      2
*** 2010-09-09 21:15:52.703
---- Sort Statistics ------------------------------
Initial runs                              1
Input records                             10000001
Output records                            10000001
Disk blocks 1st pass                      58690
Total disk blocks used                    58692
Total number of comparisons performed     10104798
  Comparisons performed by in-memory sort 10098798
  Comparisons while searching for key in-memory 6000
Temp segments allocated                   1
Extents allocated                         459
Uses version 2 sort
Does not use asynchronous IO
    ---- Run Directory Statistics ----
Run directory block reads (buffer cache)  2
Block pins (for run directory)            1
Block repins (for run directory)          1
    ---- Direct Write Statistics -----
Write slot size                           49152
Write slots used during in-memory sort    2
Number of direct writes                   10011
Num blocks written (with direct write)    58690
Block pins (for sort records)             58690
Cached block repins (for sort records)    667
    ---- Direct Read Statistics ------
Size of read slots for output             524288
Number of read slots for output           2
Number of direct sync reads               58627
Number of blocks read synchronously       58690
---- End of Sort Statistics -----------------------

/* 可以看到这里实际的sort_multiblock_read_count是29,而非我们设置的128,而max intermediate merge width最大中间运行合并宽度为2;我们知道实际的SMRC有公式MIN(ROUND(SORT_AREA_SIZE/(2*2*BLOCK_SIZE))-1, _sort_multiblock_read_count)=MIN(32-1,128)=31,而此处的实际值为29; merge width = ROUND(SORT_AREA_SIZE/(2*SMRC*BLOCK_SIZE))-1= round( 1048576/(2*29*8k))-1= round(2.2)-1=2-1=1;看起来实际的公式有所修正。*/

SQL> drop index ind_youyus;
alter session set sort_area_size=524288000;
alter session set sort_area_size=524288000;
create index ind_youyus on youyus(t1,t2) nologging;

Index dropped.

Elapsed: 00:00:00.04
SQL>
Session altered.

Elapsed: 00:00:00.00
SQL>
Session altered.

Elapsed: 00:00:00.00
SQL>

Index created.
Elapsed: 00:00:36.82

---- Sort Parameters ------------------------------
sort_area_size                    524288000
sort_area_retained_size           524288000
sort_multiblock_read_count        128
max intermediate merge width      225
*** 2010-09-09 21:32:06.517
---- Sort Statistics ------------------------------
Initial runs                              2
Number of merges                          1
Input records                             10000001
Output records                            10000001
Disk blocks 1st pass                      58690
Total disk blocks used                    58692
Total number of comparisons performed     17571986
  Comparisons performed by in-memory sort 10098438
  Comparisons performed during merge      7473532
  Comparisons while searching for key in-memory 16
Temp segments allocated                   1
Extents allocated                         459
Uses version 2 sort
Does not use asynchronous IO
    ---- Run Directory Statistics ----
Run directory block reads (buffer cache)  3
Block pins (for run directory)            1
Block repins (for run directory)          2
    ---- Direct Write Statistics -----
Write slot size                           1048576
Write slots used during in-memory sort    50
Number of direct writes                   460
Num blocks written (with direct write)    58690
Block pins (for sort records)             58690
Cached block repins (for sort records)    1
    ---- Direct Read Statistics ------
Size of read slots for output             1048576
Number of read slots for output           500
Number of direct sync reads               58563
Number of blocks read synchronously       58690
---- End of Sort Statistics -----------------------

/* 10g中引入了新的排序算法, 排序初始化运行完成后,会保存初始数据集的键值到内存中,在进行数据集进行合并时,会根据键值来选择数据集。从trace文件中可以看到这样的统计信息:Comparisons while searching for key in-memory 16;*/

/* 可以看到write slot的大小也随sort_area_size变化,sort_area_size增大的同时Number of direct writes由10011次下降到460次,此外read slots的总大小(524288*2=1048576=sort_area_size,1048576*500=sort_area_size) */

/* 在合并merge阶段,因为读取缓存足够大,因此合并次数下降到1 */
to be continued ..............
import time, os, gc, sys, urandom from media.display import * from media.media import * from machine import TOUCH try: # 显示模式选择:可以是 "VIRT"、"LCD" 或 "HDMI" DISPLAY_MODE = "LCD" # 根据模式设置显示宽高 if DISPLAY_MODE == "VIRT": # 虚拟显示器模式 DISPLAY_WIDTH = ALIGN_UP(1920, 16) DISPLAY_HEIGHT = 1080 elif DISPLAY_MODE == "LCD": # 3.1寸屏幕模式 DISPLAY_WIDTH = 800 DISPLAY_HEIGHT = 480 elif DISPLAY_MODE == "HDMI": # HDMI扩展板模式 DISPLAY_WIDTH = 1920 DISPLAY_HEIGHT = 1080 else: raise ValueError("未知的 DISPLAY_MODE,请选择 'VIRT', 'LCD' 或 'HDMI'") # 根据模式初始化显示器 if DISPLAY_MODE == "VIRT": Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60) elif DISPLAY_MODE == "LCD": Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True) elif DISPLAY_MODE == "HDMI": Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True) width = DISPLAY_WIDTH height = DISPLAY_HEIGHT # 初始化媒体管理器 MediaManager.init() fps = time.clock() # 创建绘制的图像 img = image.Image(width, height, image.RGB565) img.clear() # 设置默认画笔颜色和大小 current_color = (0, 255, 0) # 默认绿色 brush_size = 10 # 默认画笔大小 # 定义画布中的按钮区域 clear_button_area = (width - 100, 0, 100, 50) # 清除按钮区域(右上角) color_button_area = (0, 0, 130, 50) # 颜色选择按钮区域(左上角) # 实例化 TOUCH 设备 0 tp = TOUCH(0) last_point = None # 记录上一个触摸点 def draw_clear_button(): # 绘制清除按钮 img.draw_rectangle(clear_button_area[0], clear_button_area[1], clear_button_area[2], clear_button_area[3], color=(255, 0, 0),fill=True) img.draw_string_advanced (clear_button_area[0] + 10, clear_button_area[1] + 10,30, "清除", color=(255, 255, 255), scale=2) def draw_color_buttons(): # 绘制颜色选择按钮 img.draw_rectangle(color_button_area[0], color_button_area[1], color_button_area[2], color_button_area[3], color=(255, 255, 0),fill=True) img.draw_string_advanced (color_button_area[0] + 10, color_button_area[1] + 10,30, "随机颜色", color=(0, 0, 0), scale=2) def select_color(x, y): global current_color # 如果点击了颜色选择区域,则随机更改颜色 if color_button_area[0] <= x <= color_button_area[0]+color_button_area[2] and color_button_area[1] <= y <= color_button_area[1]+color_button_area[3]: current_color = (urandom.getrandbits(8), urandom.getrandbits(8), urandom.getrandbits(8)) print(f"select_color to {current_color}") # 更新触点颜色 img.draw_circle(color_button_area[0]+200,25,25,color=current_color, thickness=3,fill=True) def check_clear_button(x, y): # 检查是否点击了清除按钮 if clear_button_area[0] <= x <= clear_button_area[0]+clear_button_area[2] and clear_button_area[1] <= y <= clear_button_area[1]+clear_button_area[3]: img.clear() # 清除画布 def draw_line_between_points(last_point, current_point): """在两个触摸点之间绘制连线,插入中间点以平滑移动""" if last_point is not None: # 计算两点之间的距离 dx = current_point.x - last_point.x dy = current_point.y - last_point.y distance = (dx**2 + dy**2) ** 0.5 # 如果距离大于30,则不进行绘制 if distance > 30: return # 设定最小距离,如果两个点之间的距离大于该值,则进行插值 min_distance = 10 # 可以调整此值来改变插值的密度 if distance > min_distance: steps = int(distance // min_distance) # 计算插值的步数 for i in range(1, steps + 1): # 插值计算中间点 new_x = last_point.x + i * dx / (steps + 1) new_y = last_point.y + i * dy / (steps + 1) # 绘制圆点 img.draw_circle(int(new_x), int(new_y), brush_size, color=current_color, thickness=3, fill=True) # 最后绘制当前点 img.draw_circle(current_point.x, current_point.y, brush_size, color=current_color, thickness=3, fill=True) while True: fps.tick() # 检查是否在退出点 os.exitpoint() # 只读取 1 个触摸点数据 p = tp.read(1) # 如果返回的 p 为空元组,表示没有触摸 if p != (): for idx, point in enumerate(p, start=1): # 对触摸点进行编号,从 1 开始 # 如果触摸区域为颜色选择按钮,则随机选择颜色 select_color(point.x, point.y) # 如果触摸区域为清除按钮,则清除画布 check_clear_button(point.x, point.y) # 绘制当前点上一个点之间的线段 draw_line_between_points(last_point, point) # 更新上一个触摸点和上次触摸的时间 last_point = point # 绘制按钮和其他元素 draw_clear_button() draw_color_buttons() # 显示绘制结果 Display.show_image(img) time.sleep_ms(1) except KeyboardInterrupt as e: print(f"user stop") except BaseException as e: print(f"Exception '{e}'") finally: # 销毁 display Display.deinit() os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) time.sleep_ms(100) # 释放媒体缓冲区 MediaManager.deinit() 以如上触摸代码为例子,修改上述ui界面的代码,能让其正常实现触摸调节
最新发布
08-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值