数据库的并行度使用需要很谨慎,很容易造成数据库运行缓慢以及严重的等待。
比较常见的由于 并行度
设置错误导致的等待事件:
- PX Deq Credit: send blkd
- PX Deq Credit: need buffer
错误的并行度设置往往可能是由于在创建索引或者重建索引时开启并行度创建,后来忘记关闭导致!
createindex<indexname>on<table>(<columns>)parallel4; alterindex<indexname>rebuildparallel4;
✅ 使用并行度设置后的正确操作:
alterindex<indexname>noparallel;
当我们遇到这样的等待事件很严重时,可以使用下方脚本快速查看是否存在不正确的并行度设置!
📢 注意: 以下脚本已经过内部测试,但是,不保证它对您有用。确保在使用前在测试环境中运行它。
该 SQL 查询当前数据库主机 CPU 数以及每个 CPU 默认的并行度:
colnameformata30colvalueformata20RemHowmanyCPUdoesthesystemhave?RemDefaultdegreeofparallelismisRemDefault=parallel_threads_per_cpu*cpu_countRem-------------------------------------------------; selectsubstr(name,1,30) Name , substr(value,1,5) Valuefromv$parameterwherenamein ('parallel_threads_per_cpu' , 'cpu_count' );
该 SQL 检查当前数据库中所有用户中存在不同并行度的 表
:
setpagesize1000colownerformata30coldegreeformata10colinstancesformata10RemNormallyDOP :=degree*InstancesRemSeethefollowingNotefortheexactformula. RemNote:260845.1OldandnewSyntaxforsettingDegreeofParallelismRemHowmanytablesauserhavewithdifferentDOPsRem-------------------------------------------------------; select*from ( selectsubstr(owner,1,15) Owner , ltrim(degree) Degree, ltrim(instances) Instances, count(*) "Num Tables" , 'Parallel'fromall_tableswhere ( trim(degree) !='1'andtrim(degree) !='0' ) or( trim(instances) !='1'andtrim(instances) !='0' ) groupbyowner, degree , instancesunionselectsubstr(owner,1,15) owner , '1' , '1' , count(*) , 'Serial'fromall_tableswhere ( trim(degree) ='1'ortrim(degree) ='0' ) and( trim(instances) ='1'ortrim(instances) ='0' ) groupbyowner) orderbyowner;
📢 注意: 如果查询出 Parallel
列的值为 Serial
就证明并行度都是 1,为正常。
该 SQL 检查当前数据库中所有用户中存在不同并行度的 索引
:
setpagesize1000RemHowmanyindexesauserhavewithdifferentDOPsRem---------------------------------------------------; select*from ( selectsubstr(owner,1,15) Owner , substr(trim(degree),1,7) Degree , substr(trim(instances),1,9) Instances , count(*) "Num Indexes", 'Parallel'fromall_indexeswhere ( trim(degree) !='1'andtrim(degree) !='0' ) or( trim(instances) !='1'andtrim(instances) !='0' ) groupbyowner, degree , instancesunionselectsubstr(owner,1,15) owner , '1' , '1' , count(*) , 'Serial'fromall_indexeswhere ( trim(degree) ='1'ortrim(degree) ='0' ) and( trim(instances) ='1'ortrim(instances) ='0' ) groupbyowner) orderbyowner;
📢 注意: 如果查询出 Parallel
列的值为 Serial
就证明并行度都是 1,为正常。
该 SQL 检查具有不同 DOP 的索引的表:
coltable_nameformata35colindex_nameformata35RemTablesthathaveIndexeswithnotthesameDOPRem!!!!!Thiscommandcantakesometimetoexecute!!!Rem---------------------------------------------------; setlines150selectsubstr(t.owner,1,15) Owner , t.table_name , substr(trim(t.degree),1,7) Degree , substr(trim(t.instances),1,9) Instances, i.index_name , substr(trim(i.degree),1,7) Degree , substr(trim(i.instances),1,9) Instancesfromall_indexesi, all_tablestwhere ( trim(i.degree) !=trim(t.degree) ortrim(i.instances) !=trim(t.instances) ) andi.owner=t.ownerandi.table_name=t.table_name;
📢 注意:查询结果为空代表没有不同 DOP 的索引的表,正常。