2011-11-16 60 views
1

我正在閱讀「高性能MySQL」一書,並嘗試使用新的數據庫測試一些東西。InnoDB表上的MySQL索引 - 不能正常工作?

我不知道如果我做錯了什麼,但..

我有一個表稱爲table_users

結構:

ID(Integer) 
FullName(Char) 
UserName(Char) 
Password(Char) 
SecurityID(TinyINT) 
LocationID(TinyINT) 
Active(TinyINT) 

我的指標如下:

PRIMARY : ID 
FullName : UNIQUE : FullName 
FK_table_users_LocationID (foreign key reference) : INDEX : LocationID 
FK_table_users_SecurityID (foreign key reference) : INDEX : SecurityID 
Active : INDEX : Active 

全部是BTREE

在閱讀這本書,我嘗試使用下面的MySQL語句來查看與SELECT語句涉及

EXPLAIN 
SELECT * FROM table_users WHERE 
FullName = 'Jeff'; 

無論WHERE語句指向這個電話,額外的結果就是無論是演員沒有什麼或在哪裏使用如果我選擇ID ... WHERE FullName ='傑夫'它返回使用where,使用索引。但不是每當我做SELECT全名.... WHERE FullName ='傑夫'..

我不熟悉索引,並試圖把我的頭圍繞他們有點混淆與此。如果我引用索引列,他們不應該返回使用索引嗎?

謝謝。

回答

2

使用索引並不意味着它的含義。看看覆蓋索引。如果它表示「使用索引」,這意味着mysql可以在不讀取實際行的情況下爲您的查詢返回數據。如果表的偶數列在索引中,SELECT * - 只能使用覆蓋索引。通常情況並非如此。

我似乎記得高性能Mysql中的一章,其中討論了覆蓋索引以及如何閱讀EXPLAIN結果。

+0

謝謝,所以基本上我的索引應該沒問題,額外的只是告訴我它是否可以使用索引返回結果,或者是否需要真正在表中搜索它? – Jeff

+0

對。你所要求的所有數據都在索引本身 –

1

您使用的是哪個版本的MySQL?這是一個測試我的Percona服務器5.5.16上運行:

mysql> create table table_users ( 
    id int auto_increment primary key, 
    fullname char(20), 
    username char(20), 
    unique key (fullname) 
); 
Query OK, 0 rows affected (0.03 sec) 

mysql> insert into table_users values (default, 'billk', 'billk'); 
Query OK, 1 row affected (0.00 sec) 

mysql> explain select * from table_users where fullname='billk'\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: table_users 
     type: const 
possible_keys: fullname 
      key: fullname 
     key_len: 21 
      ref: const 
     rows: 1 
     Extra: 
1 row in set (0.00 sec) 

這表明它使用的全名索引,通過一個恆定值往上看,但它不是僅索引查詢。

mysql> explain select fullname from table_users where fullname='billk'\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: table_users 
     type: const 
possible_keys: fullname 
      key: fullname 
     key_len: 21 
      ref: const 
     rows: 1 
     Extra: Using index 
1 row in set (0.00 sec) 

這是符合市場預期,這是能夠得到全名稱指數的全名欄,所以這是一個僅索引查詢。

mysql> explain select id from table_users where fullname='billk'\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: table_users 
     type: const 
possible_keys: fullname 
      key: fullname 
     key_len: 21 
      ref: const 
     rows: 1 
     Extra: Using index 
1 row in set (0.00 sec) 

在搜索上全稱但取出的主鍵也僅索引的查詢,因爲InnoDB二級索引的(例如,唯一密鑰)的葉節點隱含包含主鍵值。所以這個查詢能夠遍歷BTREE的全名,作爲獎勵,它也得到了ID。

mysql> explain select fullname, username from table_users where fullname='billk'\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: table_users 
     type: const 
possible_keys: fullname 
      key: fullname 
     key_len: 21 
      ref: const 
     rows: 1 
     Extra: 
1 row in set (0.00 sec) 

只要選擇列表包含任何不屬於索引的列,它就不能再是僅索引查詢。首先搜索BTREE的全名,找到主鍵值。然後它使用該id值遍歷聚集索引的BTREE,這是InnoDB如何存儲整個表。在那裏它找到給定行的其他列,包括用戶名。

+0

我正在使用5.5.11,我想我只是沒有正確理解索引的想法,但你的回答給了我一個更好的理解 – Jeff