6
|
Don Branson marios · 技术社区 · 15 年前 |
![]() |
1
13
[最新编辑] 我的 关于在(name,id)上创建适当的索引以替换(name)上的索引,请参见下文。(这不是对原始问题的回答,因为原始问题不允许任何数据库更改。) 以下是我的陈述 还没有测试过。可能有一些明显的原因,这些都不起作用。事实上我从来没有这样做过 建议 写这样的陈述(冒着为这种荒谬的建议而被彻底抨击的风险。) 偶然地 ,利用 关于Don提供给我们的数据。此语句不等同于原始SQL,这些语句是为 特例 正如唐所描述的那样。
还有人提出了索引合并的想法。我之前已经放弃了这个想法,一个优化器计划在不消除任何rowid的情况下匹配上千万个rowid。
这些语句与OP查询有根本的不同。它们旨在返回与OP查询不同的结果集。这个
发生
返回所需的结果集,因为数据有一个奇怪的保证。唐告诉我们
如果是这样,也许我们可以利用这些信息。如果
[/最新编辑] [编辑]
原始答复:
好的,那是 不 问题的答案 ,但这是解决性能问题的正确答案。(您没有指定对数据库的更改,但在本例中,更改数据库是正确的答案。)
请注意,如果在上定义了索引
重新评估您对结果集的需求。。。你需要回来吗
对于特定名称,可以提交第二个查询以获取关联的
如果你真的 对于指定的结果集,您可以尝试一些替代方案,看看性能是否更好。我对这些都不抱太大希望:
或
或
更新:正如其他人敏锐地指出的,使用这种方法,我们正在测试和比较替代查询的性能,这是一种命中或未命中的方法。(我不同意这是随机的,但我同意这是偶然的。)
不用说,表上的统计信息应该是最新的,我们应该使用SQL*Plus AUTOTRACE,或者至少解释一下查看查询计划的计划。 但是,没有一个建议的替代查询真正解决了性能问题。 提示可能会影响优化器选择不同的计划,基本上通过索引满足订单,但我对此不抱太大希望。(我不认为第一行提示适用于GROUP BY,而索引提示可能适用。)我可以看到这种方法的潜力,在这样一种场景中,有大量空的、稀疏的数据块,而ny通过索引访问数据块,实际上可能会大大减少拉入内存的数据块。。。但这种情况将是例外,而不是常态。 更新:正如Rob van Wijk指出的,使用Oracle跟踪工具是识别和解决性能问题的最有效方法。 没有解释计划或SQL*加自动跟踪输出的输出,我只是在这里猜测。 我怀疑您现在遇到的性能问题是,必须引用表数据块才能获得指定的结果集。
这是无法回避的,查询不能仅从一个索引中得到满足,因为没有一个索引同时包含
即使查询的优化器计划使用其中一个索引,它仍然必须从数据块中检索关联的行,以便获取另一列的值。如果没有谓词(no WHERE子句),优化器可能会选择全表扫描,并且可能会执行排序操作(<10g)。(同样,解释计划将显示优化器计划,AUTOTRACE也是如此。) 这里我还假设(大假设)两个列都被定义为NOTNULL。 您还可以考虑将表定义为索引组织表(IOT),特别是如果这些表是表中仅有的两列的话。(物联网不是万灵药,它有自己的一系列性能问题。) 您可以尝试重新编写查询(除非在数据库环境中是一个数据库更改,这也是一个冗长的数据库),我们认为查询与表和索引一样是数据库的一部分。 同样,如果没有谓词,优化器可能不会使用索引。通过添加提示、测试以下各项的组合,您可以让查询计划使用现有索引之一快速获取返回的第一行:
(更新:其他人指出,优化器可能会选择基于ROWID合并两个索引。这是一种可能性,但如果没有谓词来消除某些行,这可能是一种更昂贵的方法(匹配100万个ROWID)来自两个索引,尤其是在匹配的基础上不排除任何行时。) 但是,如果没有一些性能统计数据,所有这些理论都不等于蹲起。 在不改变数据库中任何其他内容的情况下,加快查询速度的唯一希望(我能想到)是确保对排序操作进行了调整,以便(必需的)排序操作可以在内存中执行,而不是在磁盘上执行。但这并不是正确的答案。优化器可能根本没有执行排序操作,而是执行哈希操作(10gR2+),在这种情况下,应该进行调优。排序操作只是我的一个猜测,基于过去使用Oracle 7.3、8、8i、9i的经验。)
一个严肃的DBA会对你的未来产生更多的问题
|
![]() |
2
2
查询不能通过查看或随机建议一些等价的查询来优化,不管它们的意图有多好。 您、我们或优化器需要了解有关数据的统计信息。然后,您可以使用解释计划或SQL之类的工具进行测量 Trace/tkprof,甚至是来自SQL的简单自动跟踪工具 加
你的整个桌子看起来怎么样?请显示一个描述输出。 当做 |
![]() |
3
1
“该表非常大(有1000万行)” 如果无法更改数据库(添加索引等)。那么您的查询将别无选择,只能读取整个表。因此,首先,确定这需要多长时间(即从表1中选择ID和名称的时间)。你不会比那更快得到它的。 它必须做的第二步是区分。在10g+中,应使用哈希分组。在此之前,它是一个排序操作。前者更快。如果您的数据库是9i,那么您可以通过将1000万行复制到10g数据库中并在那里进行操作来获得改进。 或者,分配内存(google ALTER SESSION SET SORT\u AREA\u SIZE)。这可能会损害数据库上的其他进程,但DBA不会给您太多选择。 |
![]() |
4
0
这肯定会使用id上的索引,但如果它执行得快,则必须尝试。 |
![]() |
5
0
我对一个群体有着模糊的记忆,因为它比一个独特的群体快得令人费解。 |
![]() |
6
0
不知道这是否有帮助。。。 |
![]() |
7
0
|
![]() |
8
0
你可以试试类似的东西
不确定这是否会比原来的慢或快,因为我不完全了解您的表是如何设置的。如果每个ID总是有相同的名称,并且ID是唯一的,我真的看不出区别的意义。 |
![]() |
9
0
有开发环境/数据库来测试这些东西吗? 数据必须多及时? 如果表的副本已经按id和名称进行了分组,并有适当的索引,该如何处理?可以将批处理作业配置为每晚刷新一次新表。
将所有的id和名称对导出到一个备用数据库中,在那里您可以根据自己的利益进行分组和索引,并让DBA保持所有自以为是的僵硬,怎么样? |
![]() |
10
0
这可能表现更好。正如您所说,它假定给定id的名称始终相同。
|
![]() |
11
0
如果为某个给定的
这两个查询都将使用上的索引
如果你还需要
有关性能详细信息,请参见我的博客中的条目: |
![]() |
S. Jacson · 任意两台发电机的速度差(内置功能) 2 年前 |
![]() |
Sadeq Dousti · 相当于“嵌套删除”的执行性能SQL查询 2 年前 |
![]() |
Prince · 复制大型文件需要更多时间 2 年前 |
![]() |
Sagar · 为什么在循环之外声明变量会更快? 2 年前 |
![]() |
seco · 如何在不挂起页面的情况下加载JS 2 年前 |