我是Oracle的新手(在11gR2上工作)。我有一个表格,里面有大约1000万条记录,这个非常简单的查询:
SELECT t.col1, t.col2, t.col3, t.col4, t.col5, t.col6, t.col7, t.col8, t.col9, t.col10
FROM TABLE t
WHERE t.col1 = val1
AND t.col11 = val2
AND t.col12 = val3
AND t.col13 = val4
查询目前大约需要30秒/ 1分钟。
我的问题是:如何提高效果?经过大量的研究,我发现了提高性能的最经典方法,但我遇到了一些问题:
分区:实际上,该表在其他项目中使用并且影响太大。此外,只有在每天插入表格中的行数时才会延迟问题。
添加索引:事实是,WHERE子句中使用的列不是查询返回的列(除了一个)。因此,我还没有找到合适的索引。据我所知,在12~13列上设置索引并没有多大意义(或者是这样吗?)。
物化观点:我必须说我从未使用它们,但我明白维护成本非常高,我的表经常更新。
我认为最好的方法是添加一个合适的索引,但我找不到应该创建它的正确列。
答案 0 :(得分:1)
如果您的查询导致所有行的一小部分,则索引有意义。您将在WHERE子句中使用的所有四列上创建一个索引。
如果匹配的记录太多,则会进行全表扫描。您可以使用PARALLEL提示在并行线程中完成此操作来加快速度:
SELECT /*+parallel(t,4)*/
t.col1, t.col2, t.col3, t.col4, t.col5, t.col6, t.col7, t.col8, t.col9, t.col10
FROM TABLE t
WHERE t.col1 = val1 AND t.col11 = val2 AND t.col12 = val3 AND t.col13 = val4;
答案 1 :(得分:0)
WHERE子句中引用的每个列上的索引将有助于针对具有大量行的表执行查询,其中您正在寻找一个小子集,即使WHERE子句中的列未返回SELECT列列表。 当然,缺点是索引会阻碍插入/更新性能。因此,在加载具有大量记录的表时,您可能需要在加载之前禁用/删除索引,然后再重新创建/启用它们。
答案 2 :(得分:0)
拥有10百万条记录的表格相当简单。您只需要创建一个合适的索引。哪个列选择索引 - 取决于它们的内容。例如,如果您的列只包含“1”和“0”,或“是”和“否”,则不应将其编入索引。包含更多不同的值列 - 索引的效果越大。您还可以在两个或三个(以及更多)列或基于函数的索引上创建索引(在这种情况下,索引包含SQL函数的结果,而不是列值)。您还可以在表格上创建多个索引。
在任何情况下,如果您的查询选择了超过所有表记录的20-30%,索引将无济于事。
你也说过这张桌子被许多人使用。在这种情况下,您需要配合它们以避免重复索引。