说明:
有的时候需要查看刚执行过的sql的执行计划,explain不太适用。尤其是一些场景下慢SQL一直在执行,没有执行结束。这个时候可以通过v$cacheplan获取cache_item,再通过cache_item来dump 执行计划(sql硬解析完就可以生成执行计划)。但是步骤繁琐,操作麻烦,因此分享一个在python3上编写的脚本,可以快速方便的自动获取。
环境依赖:
python3.7 +
dmPython 包
步骤:
1)拷贝脚本到服务器,满足上面环境依赖,和数据库网络互通即可。
注:dmPython 包的导入不再赘述,可查阅官方平台:
2)修改数据库的连接参数
3)执行脚本
python3 get_sql_plan.py
4)输入要查看执行计划的sql语句(部分语句或者涉及的表都可)
5)会弹出过滤后满足条件的所有sql语句,选择需要查看的一条,复制输入cache_item
代码如下:get_sql_plan.py
import dmPython
import os
#DM数据库参数修改
DM_IP='192.168.136.141'
DM_PORT=5236
DM_USER='SYSDBA'
DM_PASS='SYSDBA'
##############
sql_text = input("choose a table in sql_text :")
print("select cache_item, sqlstr from v$cachepln where sqlstr like '%s' ;")
try:
conn = dmPython.connect(user=DM_USER, password=DM_PASS, server=DM_IP, port=DM_PORT)
cursor = conn.cursor()
try:
#excute sql
cursor.execute('select cache_item, sqlstr from v$cachepln where sqlstr like \'%%%s%%\' ;' %(sql_text))
print('python: excute success!')
except (dmPython.Error, Exception) as err:
print(err)
values = cursor.fetchall()
for c1 in values:
print ("######cache_item: ")
print (int(c1[0]))
print (c1[1])
cursor.close()
conn.close()
except (dmPython.Error, Exception) as err:
print(err)
plan_id = input("choose a cache_item id :")
#plan_id=139693415934064
os.system('echo >/home/dmdba/sqlplntest.log')
#print ('alter session set events \'immediate trace name plndump level %s , dump_file \'\'/tmp/sqlplntest.log\'\'\' ' %(int(plan_id)))
try:
conn = dmPython.connect(user=DM_USER, password=DM_PASS, server=DM_IP, port=DM_PORT)
cursor = conn.cursor()
try:
#excute sql
cursor.execute ('alter session set events \'immediate trace name plndump level %s , dump_file \'\'/home/dmdba/sqlplntest.log\'\'\' ' %(int(plan_id)))
print('python: excute success!')
except (dmPython.Error, Exception) as err:
print(err)
cursor.close()
conn.close()
#conn.close()
except (dmPython.Error, Exception) as err:
print(err)
with open(r'/home/dmdba/sqlplntest.log', encoding='utf-8') as f:
plan_info = f.read()
f.close()
print(plan_info)