一次索引导致查询缓慢问题
来源:互联网 发布:测试工程师知乎 编辑:程序博客网 时间:2024/05/16 09:00
今天据项目上反应有一条sql语句在查询77分钟后仍没有返回结果,sql如下:
SELECT T.*
FROM (SELECT 'GET' TYPE,
SUM(CASE
WHEN NVL(RESPONSE_TIME, 0) > NVL(SUSPEND_TIME, 0) AND
NVL(RESPONSE_TIME, 0) - NVL(SUSPEND_TIME, 0) -NVL(RESUME_TIME, 0) > 0 THEN
NVL(RESPONSE_TIME, 0) - NVL(SUSPEND_TIME, 0) -NVL(RESUME_TIME, 0)
ELSE RESPONSE_TIME
END) RESPONSE_TIME,
SUM(CONTENT_LENGTH) CONTENT_LENGTH,
ROUND(SUM(NVL(CONTENT_LENGTH, 0)) * 8000 / 1024 /
SUM(CASE
WHEN NVL(RESPONSE_TIME, 0) > NVL(SUSPEND_TIME, 0) AND
NVL(RESPONSE_TIME, 0) - NVL(SUSPEND_TIME, 0) -NVL(RESUME_TIME, 0) > 0 THEN
NVL(RESPONSE_TIME, 0) - NVL(SUSPEND_TIME, 0) -NVL(RESUME_TIME, 0)
ELSE RESPONSE_TIME
END),
3) SPEED
FROM CUPID T
WHERE (T.TTIME >= TIMESTAMP' 2012-02-06 00:00:00' AND T.TTIME < TIMESTAMP' 2012-02-06 23:59:59')
AND exists (SELECT * FROM s_cupidSS WHERE UPPER(T.URI_MAIN) like SS.VALUE)
AND CONTENT_LENGTH IS NOT NULL
AND ((NVL(RESPONSE_TIME, 0) > NVL(SUSPEND_TIME, 0) AND
NVL(RESPONSE_TIME, 0) - NVL(SUSPEND_TIME, 0) - NVL(RESUME_TIME, 0) > 0) OR RESPONSE_TIME IS NOT NULL)
AND PACKETS > 3
GROUP BY 'GET'
ORDER BY SPEED) T
WHERE ROWNUM <= 5000
sql有点长 但是还是坚持贴出来,看到sql第一眼就觉得是exists这个问题 因为在s_cupid 表中仅有1条数据,使用exists明显是不正确的。所以就改成了in,改后sql如下:
AND UPPER(T.URI_MAIN) in
(SELECT distinct UPPER(T.URI_MAIN) FROM S_HOST_380327B34 SS
WHERE UPPER(T.URI_MAIN) like SS.VALUE)
从新跑sql,结果跑了33分钟,这显然不对,因此对CUPID和s_cupid做分析,其中cupid表是个分区表,按ttime分区,及按小时分区,ttime上有索引,这张表每小时的数据量大约在5,000,000条左右,那么以T.TTIME >= TIMESTAMP' 2012-02-06 00:00:00' AND T.TTIME < TIMESTAMP' 2012-02-06 23:59:59'为时间段查询数据,也就是查询18个分区的数据,查看此sql的执行计划
1、set autotrace trace exp;
2、sql语句
3、
PARTITION RANGE ITERATOR | | 235 | 9870 | 348 (0)| 00:00:05 | 505 | 5
TABLE ACCESS BY LOCAL INDEX ROWID| cupid | 235 | 9870 | 348 (0)| 00:00:05 | 505 | 5
INDEX RANGE SCAN | GETTTIME | 1510 | | 7 (0)| 0
这个执行计划明显是走了ttime上的索引,因此选择禁掉索引,/*+ no_index(T,gettime)*/,在这里先前使用/*+ no_index(cupid,gettime)*/发现执行计划没变,也就说hint没起作用,后来想到表在有别名的时候必须在hint中使用别名,否则无效;
修改完后重新获得执行计划如下:
| FILTER | | | | | | | |
| 6 | PARTITION RANGE ITERATOR| | 235 | 9870 | 957K (1)| 03:11:31 | 505 | 528 |
|* 7 | TABLE ACCESS FULL | GB_GET | 235 | 9870 | 957K (1)| 03:11:31 | 505 | 528 |
没有选择索引,而是先扫描分区列表,找到对应分区,之后对分区进行全表的扫描,此sql3分多就计算出结构,问题解决,但是要删掉索引还需谨慎,你应该确保你的环境下在使用ttime做精确定位的语句很少的时候在drop掉,另外如果使用/*+ first_row(5000) */效果会更加。
- 一次索引导致查询缓慢问题
- 一次由重复索引导致的问题
- 通过hibernate session.connection()获得数据库连接时,导致的查询缓慢甚至假死机问题
- 通过hibernate session.connection()获得数据库连接时,导致的查询缓慢甚至假死机问题
- OpenDs查询缓慢问题分析
- 记一次线上请求缓慢问题处理
- mongo3.2 数组索引作为联合索引的一部分导致的范围查询问题
- hibernate查询少量数据缓慢问题
- 运行缓慢的查询语句 监测索引的使用
- 解决因数据库一次查询数据量过大导致的内存溢出问题
- 解决AVAST杀毒软件导致系统启动缓慢的问题
- 一次mysql的查询索引的优化
- CodeIgniter需要注意错写查询条件导致数据库索引失效的问题
- 导致Lucene无法索引查询的NoClassDefFoundError
- MySQL前缀索引导致的慢查询
- Linux索引节点(inode)用满导致的一次故障
- Linux索引节点(inode)用满导致的一次故障
- Linux索引节点(inode)用满导致的一次故障
- POJ 2163 Easy Trading(我的水题之路——数组阶段n m的平均值比较)
- DecimalFormat的用法介绍
- 等概率色子问题
- 实现windows cmd中自动补全
- Linux环境下LaTeX技巧及错误处理汇总
- 一次索引导致查询缓慢问题
- Open stack
- cygwin安装后,修改本机登录的默认用户
- 无法通过64位的ODBC连接数据库
- 笔录(一)
- Android命令行启动程序的方法
- Berkeley DB程序员参考--目录
- Android NFS 文件系统
- 组合框和字符串