我们假设我们有一名员工。我在这张桌子上执行了2个以下的查询。
查询1
select * from employee where email_id = 'admin@xyz.com'
查询2
select * from employee where email_id = 'abc@xyx.com'
假设我有一个巨大的数据集,我正在执行此查询。观察是Query1比Query2花费的时间少得多。我还检查了列email_id上没有索引。我的假设是服务器以某种方式缓存Query1而不是Query2。如果这是真的那么我如何强制服务器缓存Query2?另外,如果可能的话,我想在不使用索引的情况下优化Query2。有什么建议吗?
答案 0 :(得分:1)
如果没有email_id
上的索引,我们会希望两个查询花费相同的时间,即在employees表上执行全表扫描所花费的时间。那么为什么一个查询的返回速度比另一个快得多呢?
假设:
select * from employee where email_id = ':1'
)。admin
电子邮件地址。包含文字的查询通常是一件坏事:每个版本都必须进行硬解析,它们会占用游标缓存中的空间。但它们也可能有不同的执行路径(因为它们是单独解析的)或性能配置文件。这似乎就是这种情况。如果没有索引,访问路径将是相同的,但由于缓存,总耗用时间可能会有所不同。
可能有两种可能的缓存。
employee
admin@xyz.com
记录的块已经在数据库缓冲区缓存中,因此查询不必读取整个表。employee
的{{1}}记录会缓存在那里。因此,可以缓存admin@xyz.com
的两个原因。显然,任何员工都可能如此。但似乎人们会比admin@xyz.com
更频繁地寻找admin@xyz.com
。很简单,(不知道您的应用程序或您的数据),管理员用户经常被查询,因此比任何其他随机用户更有可能在缓存中。
"如何强制服务器缓存Query2?"
如果joe.soap@xyz.com
用户被意外缓存 - 它只是在缓冲区保持温暖,因为它经常被查询 - 你真的不能做多少。确实,我们可以将表格固定在内存中,但这通常是一个坏主意。大多数情况下,数据库是一个比我们更好的资源管理器:如果块没有保留在DB Buffer Cache中,因为它们不经常使用(假设DBC是大小正确)。
如果您的应用程序正在使用结果集缓存,那么您可以显式检索admin
的记录。但是你不能为所有用户做到这一点,原因与以前一样:如果经常使用记录,你就不想将记录固定在内存中。
这为我们带来了目标。你想在这里优化什么?用户子集的访问时间/或任何用户的访问时间?如果是后者,则需要abc@xyz.com
上的索引。
答案 1 :(得分:0)
更多假设: