为什么在oracle SQL中执行具有两个不同值的查询所花费的时间相差很多

问题描述:

假设我们有一个表员工。我在这个表上执行2个以下的查询。为什么在oracle SQL中执行具有两个不同值的查询所花费的时间相差很多

查询1

select * from employee where email_id = '[email protected]' 

查询2

select * from employee where email_id = '[email protected]' 

假设我有上我执行此查询一个巨大的数据集。观察结果是Query1比Query2花费的时间少得多。我也检查了列email_id没有索引。我的假设是服务器以某种方式缓存Query1而不是Query2。如果这是真的,那我该如何强制服务器缓存Query2?另外,如果可能的话,我希望不使用索引来优化Query2。有什么建议么?

如果没有email_id的索引,我们预计这两个查询都将花费同一时间,即在employees表上执行全表扫描所需的时间。那么为什么一个查询返回比另一个快得多呢?

假设:

  1. 你真正的查询使用硬编码值而不是绑定变量(即select * from employee where email_id = ':1')。
  2. 更具表现性的查询确实在搜索admin电子邮件地址。

包含文字的查询通常是一件坏事:每个版本都必须进行硬解析,它们会占用游标缓存中的空间。但是他们也可能有不同的执行路径(因为它们被单独解析)或性能配置文件。这似乎就是这种情况。如果没有索引,访问路径将是相同的,但由于缓存的原因,总的使用时间可能会有所不同。

有两种可能的缓存可能在使用。

  1. 意外缓存。包含employee[email protected]记录的块已经在DB缓冲区缓存中,因此查询不必读取整个表。
  2. 蓄意缓存。有些人通过电子邮件地址查询雇员,其中使用resultset caching,并且[email protected]employee记录被缓存在那里。

因此,可以缓存[email protected]的两个原因。显然,任何员工都可能会这样。但似乎人们可能会比[email protected]更频繁地寻找[email protected]。很简单,(不知道您的应用程序或数据),管理员用户会被频繁查询,因此比任何其他随机用户更可能在缓存中。

“我该如何强制服务器缓存Query2?”

如果admin用户意外缓存 - 因为它质疑如此频繁的缓冲它只是保持温暖 - 有真的没有什么可以做。确实,我们可以在内存中添加表格,但这通常是一个糟糕的主意。大多数情况下,数据库比我们的资源管理更好:如果数据块没有保存在数据库缓冲区缓存中,这是因为它们不经常使用(假设DBC的大小正确)。

如果您的应用程序正在使用结果集缓存,那么您可以显式检索[email protected]的记录。但是你不能为所有的用户这么做,出于和以前一样的原因:如果你经常使用它们,你不想把记录固定在内存中。

这将我们带入目标。你想在这里优化什么?一个子集的访问时间/或任何用户的访问时间?如果是后者,那么您需要email_id上的索引。

+0

谢谢你提及许多方法的优点和缺点。我反对索引的原因是我想优化一部分用户的查询。 – FTW

更多的假设:

  1. 一旦运行QUERY2,它会在你的缓存,并运行它的第二次,你将有一个高速缓存命中,除非你很久以后运行查询,它有这时已经过时了。
  2. 您正在使用强制系统绑定的cursor_sharing = FORCE
  3. 您有一些非常好的理由不使用email_id上的索引。你真的很想好好利用索引。
  4. 未来,query3和query4等等呢?
+0

我在通过问题8- |完成之前意外按下了'enter' – APC

+1

我按下输入的目的:)很好的答案APC。我upvoted。 – sandman