为什么在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表上执行全表扫描所需的时间。那么为什么一个查询返回比另一个快得多呢?
假设:
- 你真正的查询使用硬编码值而不是绑定变量(即不
select * from employee where email_id = ':1'
)。 - 更具表现性的查询确实在搜索
admin
电子邮件地址。
包含文字的查询通常是一件坏事:每个版本都必须进行硬解析,它们会占用游标缓存中的空间。但是他们也可能有不同的执行路径(因为它们被单独解析)或性能配置文件。这似乎就是这种情况。如果没有索引,访问路径将是相同的,但由于缓存的原因,总的使用时间可能会有所不同。
有两种可能的缓存可能在使用。
- 意外缓存。包含
employee
[email protected]
记录的块已经在DB缓冲区缓存中,因此查询不必读取整个表。 - 蓄意缓存。有些人通过电子邮件地址查询雇员,其中使用resultset caching,并且
[email protected]
的employee
记录被缓存在那里。
因此,可以缓存[email protected]
的两个原因。显然,任何员工都可能会这样。但似乎人们可能会比[email protected]
更频繁地寻找[email protected]
。很简单,(不知道您的应用程序或数据),管理员用户会被频繁查询,因此比任何其他随机用户更可能在缓存中。
“我该如何强制服务器缓存Query2?”
如果admin
用户意外缓存 - 因为它质疑如此频繁的缓冲它只是保持温暖 - 有真的没有什么可以做。确实,我们可以在内存中添加表格,但这通常是一个糟糕的主意。大多数情况下,数据库比我们的资源管理更好:如果数据块没有保存在数据库缓冲区缓存中,这是因为它们不经常使用(假设DBC的大小正确)。
如果您的应用程序正在使用结果集缓存,那么您可以显式检索[email protected]
的记录。但是你不能为所有的用户这么做,出于和以前一样的原因:如果你经常使用它们,你不想把记录固定在内存中。
这将我们带入目标。你想在这里优化什么?一个子集的访问时间/或任何用户的访问时间?如果是后者,那么您需要email_id
上的索引。
谢谢你提及许多方法的优点和缺点。我反对索引的原因是我想优化一部分用户的查询。 – FTW