上一篇
场景引入:
凌晨3点,你正盯着屏幕上一行执行计划发呆——明明有索引,Oracle却固执地选择了全表扫描(Full Table Scan)😫,报表跑了一小时还没结果,咖啡杯早已见底...这时候,就该祭出/*+ INDEX */
这个隐藏大招了!
它是你写给Oracle优化器的"小纸条"💌,格式长这样:
SELECT /*+ INDEX(表名 索引名) */ 字段 FROM 表名 WHERE 条件
当优化器"犯迷糊"时,用这个语法强制指定使用某个索引,就像导航软件非要绕远路,你手动切换路线一样🗺️。
典型使用场景:
UPPER(name)
) -- 强制使用emp表的idx_salary索引 SELECT /*+ INDEX(emp idx_salary) */ * FROM emp WHERE salary > 10000;
⚠️ 注意:如果索引名写错,Oracle会优雅地...忽略你的提示
/*+ INDEX(emp) */ -- 让Oracle自己挑个合适的
适合当你只知道"要用索引",但不确定具体哪个时
/*+ NO_INDEX(emp idx_salary) */ -- 禁用特定索引
某些情况下全表扫描反而更快(比如要查90%的数据)
/*+ INDEX(emp idx_dept) INDEX(dept pk_dept) */
多表关联时逐个指定,避免连环翻车
/*+ INDEX_SS(emp idx_gender_dept) */
当复合索引第一列缺失时(如只查dept_id
但索引是(gender, dept_id)
)
/*+ INDEX_COMBINE(emp idx1 idx2) */
让Oracle合并多个索引的扫描结果,适合复杂条件
ANALYZE TABLE
)、索引是否合理 INDEX_FAST_FULL_SCAN
提示在19c无效 EXPLAIN PLAN
验证 案例:有个500万行的订单表,按create_time
查询突然变慢。
-- 原SQL(优化器选择全表扫描) SELECT order_id FROM orders WHERE TRUNC(create_time) = DATE'2025-08-01'; -- 优化方案1:改写条件 SELECT order_id FROM orders WHERE create_time >= TIMESTAMP'2025-08-01 00:00:00' AND create_time < TIMESTAMP'2025-08-02 00:00:00'; -- 优化方案2:万不得已再用提示 SELECT /*+ INDEX(orders idx_create_time) */ order_id FROM orders WHERE TRUNC(create_time) = DATE'2025-08-01';
INDEX提示像SQL界的"紧急手动挡"🚗💨,关键时候能救命,但别当成日常驾驶模式,2025年Oracle 23c甚至引入了AI自动提示生成,但在此之前,掌握这些技巧依然能让你在性能优化赛中领先三圈!
(本文技术要点基于Oracle 19c-21c版本验证,2025年8月仍适用)
本文由 英泰 于2025-08-01发表在【云服务器提供商】,文中图片由(英泰)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/504282.html
发表评论