如果沒有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
上的索引。
來源
2017-07-18 08:37:24
APC
謝謝你提及許多方法的優點和缺點。我反對索引的原因是我想優化一部分用戶的查詢。 – FTW