2012-02-14 38 views

回答

5

索引在SQL中如何工作以及它提供了哪些好處?

當您爲列建立索引時,表達了您在條件表達式中查詢索引列的意圖,例如相等或範圍查詢。利用這些信息,存儲引擎可以構建一個使這種查詢更快的結構,通常將它們排列在樹結構中。 B樹是最常見的,但存在許多不同的結構,例如散列索引,空間數據的R樹索引等。每個結構都專門用於某種類型的查找。例如,哈希索引是實現平等的條件非常快,例如:

SELECT * FROM example_table WHERE type = "example"; 
SELECT * FROM example_table WHERE id = X; 

B-樹也是平等的外觀起伏相當快,但它們的主要優點是它支持範圍查詢:

SELECT * FROM example_table WHERE id > 5 AND id < 10 
SELECT * FROM example_table WHERE type = "example" and value > 25 

是非常重要的,但是,當你建立B樹索引明白,樹是在「左到右」的方式訂購。也就是說,如果您在{type,value}上構建B樹索引(讓它稱爲A),那麼您需要在類型列上具有條件以便查詢能夠使用該索引。示例索引不能用於條件完全依賴於值的查詢中。 此外,如果混合平等和範圍條件,確保平等列列在指數第一,否則該索引只能部分使用。

會有不索引什麼原因?

如果索引的選擇性很低,那麼在表掃描上可能沒有太多的收穫。比如說你有一個名爲性別的字段的索引。那麼該索引的選擇性會很低,因爲對該索引的查找將返回原表的一半行。你可以閱讀選擇一個非常簡單的解釋一下,和推理背後:http://mattfleming.com/node/192

同時,維持指標是有成本的。對於每個數據操作,索引可能需要重組。因此,將索引數量保持在針對該表的查詢所需的最低要求可能是可取的。

索引單列與索引多列之間有什麼區別?

再次,它取決於你發出查詢的類型。索引單列性別可能不是一個好主意,因爲選擇性很低。當選擇性高時,這樣的指數更有意義。例如,主鍵上的索引是一個非常好的索引,因爲選擇性很高(實際上,索引中的每個鍵都對應於記錄中的精確值),並且列上的索引具有唯一性或高度不同的值(例如slu,,密碼哈希和不能)也是很好的單列索引。

還有覆蓋指數的概念。基本上,索引中的每個葉子都包含一個指向存儲該行的表的指針(除非索引是聚簇索引,在這種情況下葉是記錄)。因此,對於每個索引命中,查詢引擎必須獲取相應的錶行,從而增加I/O操作的數量。由於I/O速度非常慢,因此您希望將其降至最低。現在,假設您經常需要查詢某些內容並獲取一些額外的列,那麼您可以創建一個覆蓋索引,爲查詢性能交易存儲空間。例如:讓我們找到誰在過去6個月(假設MySQL的)參加了所有用戶的姓名和電子郵件:

隨着{joined_at}指數:

SELECT first_name, last_name, email 
FROM users 
WHERE joined_at > NOW() - INTERVAL 6 MONTH; 

查詢解釋:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE  users ALL test   NULL NULL  NULL 873 Using where 

正如您在type欄中可以看到的那樣,查詢引擎使用了全表掃描,因爲索引選擇性太低而不適合在此查詢中使用(將返回太多結果,因此會被追蹤到表中,在I/O中花費太多)

隨着{joined_at,名字,姓氏,電子郵件}指數:現在

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE  users range test,test2  test2 8  NULL 514 Using where; 
                    Using index 

,因爲一切必要完成查詢的信息是在索引可用,查詢引擎計算,這是更好地使用索引(514行)而不是進行全表掃描。因此,您可以看到,通過使用覆蓋索引,我們可以加快部分表選擇的查詢速度,即使索引的選擇性非常小。

2

如何在SQL

索引工作,這是一個相當開放的問題,而是基本數據庫存儲,允許更快的查找信息的結構。該結構取決於實現,但通常是一種樹。

它提供了什麼好處?

查詢是優化搜索可以顯著更快。*

會有不索引什麼原因?

某些數據修改查詢可能需要更長的時間,並且存在索引的存儲成本,但一般來說,這兩個考慮因素都可以忽略不計。

索引單列與索引多列之間有什麼區別?

沒有太大的差別,但有時人們創建覆蓋索引**,索引多列以提高特定查詢的性能。


*優化搜索是搜索參數ABLE。基本上如果你這樣做WHERE FOO > 5它可以更快如果FOO索引。另一方面,WHERE h(FOO) > 5可能不會從索引中受益。

**如果在SELECT JOIN和WHERE語句中使用的所有字段也都在索引中,那麼數據庫可以檢索它需要的所有信息而無需返回基表。這被稱爲覆蓋指數。如果所有字段都在單獨的索引中,那麼它將僅使用連接的字段,然後返回基本表中的select列中的列。

+0

感謝您提供快速翔實的答案。你認爲你可以爲我詳細解釋一些嗎? SARGable是什麼意思?將多個列索引爲單個索引,還是將這些相同的多個列索引在一起,有什麼區別? – john 2012-02-14 22:47:32

+0

我已經更新了我的答案,將擴展包含在SARGable和Covering索引的思想中 – 2012-02-14 23:01:38