为了优化SELECT查询,我使用和不使用索引运行它们并测量差异。我运行了一堆不同的类似查询,并尝试选择不同的数据,以确保缓存不会丢失结果。但是,在非常大的表上,索引需要很长时间才能创建,而且我对于哪些索引是合适的有几个不同的想法。
在Oracle(或任何其他数据库)中是否可以执行查询但是在执行查询时告诉数据库不使用某个索引?或者只是完全关闭索引,但是能够轻松地将其重新打开而无需重新索引整个表格?这样可以更容易测试,因为我可以创建我正在考虑的所有索引,然后尝试使用不同的索引。
或者,有没有更好的方法来优化大型表上的查询并知道哪些索引最适合创建?
答案 0 :(得分:9)
您可以在11g -
中设置索引可见性ALTER INDEX idx1 [ INVISIBLE | VISIBLE ]
这使得优化器无法使用它,但oracle在添加或删除数据时仍会更新索引。这样可以轻松地在禁用索引的情况下测试性能,而无需删除&重建整个索引。
有关索引可见性的oracle文档,请参阅here
答案 1 :(得分:3)
您可以在查询中使用NO_INDEX提示来忽略索引 - 有关详细信息,请参阅文档。 SQL Access Advisor是一个Oracle实用程序,它将推荐索引策略。
答案 2 :(得分:3)
那么你可以用这样的方式编写查询:它不会使用索引(使用表达式而不是值)
例如
Select * from foobar where column1 = 'result' --uses index on column1
避免使用索引编号和varchar
Select * from foobar where column1 + 0 = 5 -- simple expression to disable the index
Select * from foobar where column1 || '' = 'result' --simple expression to disable the index
或者您可以使用NVL来禁用查询中的索引,而无需担心列的数据类型
Select * from foobar where nvl(column1,column1) = 'result' --i love this way :D
同样,您可以使用索引提示
像/* Index(E employee_id) */
一样使用索引。
附:这是Dan Tow的书籍SQL调优的全部转述。几天前我开始读它:)