2012-06-28 80 views
1

假設我有一個表events {id, userid, create_time, country, type, page, browser}索引的Mysql工作

我在所有列上都有索引。 如果我做一個查詢

select count(*) from events where id > ? and id < ? and userid>? and userid<? and create_time>? and create_time<? and browser=? and country=? and page=? 

我有以下問題:

  1. 將我所有的指標可以用嗎?如果沒有,如何實現這一點。
  2. 有多個列索引會更好嗎?
  3. 如果我在(id,userid,page)上有多列索引,它會被使用嗎?如果是的話,其他指標也將被使用?
  4. 如果我有多列索引包括所有列,但我的查詢不包括所有列,那麼將使用該索引?

回答

0

問:我的所有指數是否會被使用?

答:非常不可能。更有可能的是,MySQL將選擇一個具有最高選擇性(消除最多行)的索引,然後從索引引用訪問數據頁面。

MySQL可能會執行索引合併操作,但那將是罕見的例外。你真的需要做一個EXPLAIN來看看是否發生了這種情況,並且做一些工作來開發一個MySQL將其視爲最佳計劃的案例。 (有人可能完成了這項工作,並且有這樣的測試案例。)

問:如果沒有,如何做到這一點。

- 答:你不想實現這一點。你希望MySQL做什麼是產生一個最佳的計劃。索引合併計劃很可能不是您查詢的最佳計劃。這樣的操作需要MySQL將所有這些索引「匹配」在一起,這是很多繁重的工作。

問:有多列索引會更好嗎?

A:是的。特定查詢的最佳索引是覆蓋索引,其中包含查詢中引用的所有列。通常,您需要首先選擇性最高,基數最高的列。您的查詢似乎在進行範圍掃描而不是平等測試,因此您希望謂詞中的值範圍最窄的列與該列的整個值集合相比,首先在索引中。

問:如果我在(id,userid,page)上有多列索引,它會被使用嗎?

答:可能。您在該索引中的兩個主要列上有範圍掃描謂詞,所以它絕對看起來像候選人。如果這些是您的查詢中引用的唯一列,那麼它使得該索引更有可能被使用。

您的查詢文本中似乎存在格式錯誤的create_time引用。它看起來像你打算在該列上有某種謂詞。如果是這樣的話,則(id, userid, create_time)上的索引將是更好的候選者,因爲那麼查詢可以在不引用數據頁面的情況下從索引滿足。

另一方面,全面掃描數據頁面可能是一個更優化的計劃。

問:如果是的話其他指標也會被使用?

答:非常不可能。 MySQL將在表上使用「多個」索引的想法是關於MySQL如何使用索引的常見誤解。這不是問題所在,但INDEX MERGE操作不太可能是最佳方案。

問:如果我有多列索引包括所有列但我的查詢不包括所有列,那麼將使用該索引?

- 答:這是可能的。如果MySQL確定使用該索引是最佳方案,那麼它將被使用。要使用的索引越多(如果可用)就是覆蓋索引,其中只包含查詢中引用的列。

1

我的所有指數是否會被使用?

不會。只會使用一個索引。你可以在EXPLAIN的輸出中看到這個。

有多個列索引會更好嗎?

如果您有平等約束,是的。但在您的查詢中似乎不是這種情況。包含索引 - 也就是包含查詢所需的所有值的索引也很好。

如果我在(id,userid,page)上有多列索引,它會被使用嗎?

也許但我建議增加create_time,因爲這將使它成爲一個覆蓋指數。索引中不需要page,因爲它不在查詢中使用。

如果我有一個多列索引包括所有列,但我的查詢不包括所有列,那麼將使用該索引?

它取決於列的順序。如果查詢要使用create_time上的索引,則可以使用(create_time, country)上的索引代替。但是(country, create_time)上的索引無濟於事。

+0

儘管'EXPLAIN'只顯示前者,雖然與提出的問題無關,是否可以爲'JOIN','ORDER BY'和'GROUP BY'使用不同的索引? – eggyal