2012-01-30 63 views
1

就索引而言,索引所有將在WHERE子句中搜索的字段以加速SELECTS是否合適?例如,我的數據庫包含一個配置文件表,用於存儲用戶信息,如名稱,intrestCode,zip,說明和電子郵件。配置文件記錄由與用戶ID唯一對應的PRIMARY id列標識。我將zip和intrestCode作爲索引,因爲配置文件將通過zip和可能的intrestCode(SELECT `blah`,`blah`... FROM profile WHERE zip=?SELECT `blah`,`blah`... FROM profile WHERE zip=? && intrestCode=?)進行搜索。我做對了嗎?適當的索引MySQL

回答

3

聲音基本正確。你應該知道,你不能在同一個查詢相同的表使用兩個不同的指標,因此,如果您運行

CREATE INDEX `zip` ON `profile` (`zip`); 
CREATE INDEX `intrestCode` ON `profile` (`intrestCode`); 

那麼查詢

SELECT `blah`,`blah`... FROM profile WHERE zip=? && intrestCode=? 

只能仰望一個從表該指數。這裏的祕密是,你可以在兩個表創建一個單一的指標,像這樣:

CREATE INDEX `zip+intrestCode` ON `profile` (`zip`, `intrestCode`); 

MySQL能使用此爲在WHERE子句中使用單獨或者zip查詢,或同時使用zipintrestCode,但不對於在WHERE子句中僅使用intrestCode的查詢。 (這是因爲每個索引都覆蓋整個表,如果MySQL試圖從不同的表中查找zipintrestCode,那麼它將從第二個索引中檢索大量不相關的行,因此它只查看一個索引如果你希望它使用兩列的索引,你需要有一個包含兩列的索引。)

+0

問題是我不知道用戶想要怎麼搜索。有些人可能只想通過郵政編碼進行搜索,有些可能只希望通過興趣搜索,有些可能希望通過兩者進行搜索。這似乎是一種常見現象。沒有解決方案(缺少很多表格)?構建一個多聲明索引並對未使用的字段進行通配會起作用嗎?僅適用於Zip:選擇*從配置文件zip =? && intrestCode LIKE'%'。僅適用於Intrest代碼:SELECT *從配置文件WHERE zip LIKE'%'&& intrestCode =?。對於兩個:選擇*從配置文件WHERE zip =? && intrestCode = ?. – user974896 2012-01-30 01:35:14

+0

不需要。各個領域之間必須有嚴格的關係。如果你有兩個字段,你可以很容易地創建兩個索引,一個在'zip'和'intrestCode'上,另一個在'intrestCode'上。如果你有更多的領域,則更難解釋所有的組合。在這一點上,最好爲每個字段創建一個索引,並讓優化器選擇最好的一個(事件雖然無法獲得相同的效率增益)。根據數據庫的大小,根本不值得創建多列索引。這裏需要一些判斷電話。 – 2012-01-30 01:51:50

+0

還有一個問題,增加幾個索引來覆蓋很多組合,實際上會減慢速度(來UPDATE,INSERT,甚至SELECT時間?),還是隻是在磁盤空間方面代價高昂。由於成本低,磁盤空間幾乎是無限的資源。 – user974896 2012-01-30 02:07:25

0

我相信基本上是的。您應該監控數據庫,以便遇到更多問題,並根據結果優化查詢和表格。

1

索引關係數據庫是一門藝術。最好的方法是查看您將要製作的所有不同查詢,並將索引放入所涉及的列中。使用EXPLAIN可查看查詢要使用的索引。

但是,請記住,MySQL一次只能從表中使用一個索引。這就是爲什麼您可以一次將索引放在多個列上的原因。如果MySQL只需要索引開始處的列,就可以使用多列索引。在你的例子中,我會將多列索引zipintrestCode放在一起,因爲這將有助於兩個查詢。這樣你就不需要一個單獨的索引,只需zip

+0

那麼如何加速SELECT'email','name'從'profiles' WHERE'zip' =? &&'intrestCode' =? 。正如你可以看到它使用2列。我不會使用2個單獨的索引? – user974896 2012-01-30 01:06:08

+0

你做了一個多列索引:'ALTER TABLE profile ADD INDEX(zip,intrestCode)' – staticsan 2012-01-30 01:08:04

0

通常你想添加索引到你要加入或在where子句中有的列。請記住,兩列上的索引不同於兩列中的每一列上的一個索引。另外,如果您在多個列上有索引,則順序很重要。

假設您有兩個列A和B,並且具有A列和B列的兩列索引。有三種情況:

  1. 凡針對列中的一項條款:使用索引
  2. 若針對B列條款:如果不使用索引
  3. 對列A條款,B:使用索引

像staticsan說,索引是一門藝術,沒有適用於100%時間的規則。使用解釋計劃來查看您的查詢如何執行並相應地進行調整。