在过去几周里,我一直在努力提高性能,以便进行一些简单的查询。我想我会首先写出查询,然后描述当前使用的内容和我的想法。
表:约1亿行
统计数据每周收集
示例:
SELECT c1,c2,c3,c4,TO_NUMBER(c5)
FROM TABLE
WHERE CODE = 3 AND
NUMBER IN (115,433,54542,435930,22565,3293029,3222) AND
DATE BETWEEN TO_DATE('01-01-2010','DD-MM-YYYY') AND TO_DATE('01-01-2015','DD-MM-YYYY') AND
AMOUNT > 1000
目前正在使用的CODE,NUMBER和DATE列上有一个索引,但查询仍需要几分钟才能完成。在测试过的NUMBER列上还有一个索引,它的性能略好一些,但查询仍然太慢。
该表也按月按日期分区。
因为现有索引不起作用,我现在要创建自己的表,我可以自由统治。
我的想法是:
1)在CODE上创建分区或物化视图;一半的表有代码= 3,所以我的想法是这将有效地减少一半的表大小
2)DATE实际上也随时间保存;截断所有日期并以这种方式创建分区可以提高性能
3)在所有四列上创建一个索引,看它是否会提高性能。
这就是我真正拥有的一切。非常感谢任何其他建议!
答案 0 :(得分:1)
您说该表是根据DATE
列进行分区的(可能您的意思是范围分区)。
您说您有索引,但是您没有指定它们是全局的(一个索引覆盖所有分区)还是本地(每个分区一个索引)。
我提出建议的任何尝试都涉及猜测Oracle现在如何执行查询;似乎可以使用各种可能的计划。
所以我的主要建议是学习如何查看和理解执行计划。你需要了解它正在做什么才能真正了解什么可能会让它变得更好。
但我会提出一些可能适用或可能不适用的建议。
假设您的索引是全局的,那么我认为优化器可以选择 根据DATE
进行分区消除(在这种情况下,它会全面扫描相关分区)< em>或使用索引进行查找。您可以通过使用本地索引获得改进,因为它可以执行分区消除,然后在每个分区中使用索引查找(在这种情况下,索引中的DATE
将毫无意义,至少对于此查询)。
可能将AMOUNT
添加到索引会有所帮助,但这取决于AMOUNT > 1000
是否消除了大量行。
您可能会创建一个涵盖所有过滤列和所有选定列的索引,在这种情况下,索引查找可以满足查询,而无需查看该表。
答案 1 :(得分:0)
你的问题对于实际的指数是模糊的。
对于此查询,最佳索引位于(code, number, date, amount)
。
但是,您从具有100,000,000行的表中获取5年的数据。我不知道其他列的选择性如何,但这可能会返回大量数据。这可能解释了性能问题。