簡體   English   中英

索引和多列主鍵

[英]Indexes and multi column primary keys

在 MySQL 數據庫中,我有一個具有以下主鍵的表

PRIMARY KEY id (invoice, item)

在我的應用程序中,我也會經常選擇item本身,而不是只選擇invoice 我假設我會從這些列的索引中受益。

當我定義以下內容時,MySQL 不會抱怨:

INDEX (invoice),
INDEX (item),
PRIMARY KEY id (invoice, item)

但是我沒有看到任何證據(使用 DESCRIBE——我知道如何查看的唯一方法)已經為這兩列建立了單獨的索引。

構成主鍵的列是否會自動單獨索引? 有沒有比 DESCRIBE 更好的方法來探索我的表結構?

我並不熟悉mySql上的索引內部,但是我熟悉的兩個數據庫供應商產品(MsSQL,Oracle)索引是平衡樹結構,其節點被組織為列的有序元組。 index定義於( 在序列中定義

因此,除非mySql以非常不同的方式(可能不是)執行,否則任何復合索引(在多個列上) 可以被任何需要按索引中的列子進行過濾或排序的查詢使用,只要列列表是兼容的,即,如果列與完整索引中的列的順序列表相同,則列是完整索引列集的有序子集,它從實際索引序列的開頭開始,沒有差距,除了最后......

換句話說,這意味着如果在(a,b,c,d)上有索引,則對(a),(a,b)或(a,b,c)進行過濾的查詢也可以使用索引,但是需要在(b),或(c)或(b,c)上過濾的查詢將無法使用索引...

因此,在您的情況下,如果您經常需要單獨對列進行過濾或排序,則需要在該列上添加另一個索引...

我個人使用phpMyAdmin來查看和編輯MySQL數據庫的結構。 它是一個Web應用程序,但它在本地Web服務器上運行良好(我在我的機器上運行apache實例和phpPgAdmin)。

對於(invoice, item)的復合關鍵字,它的作用類似於(invoice, item)invoice的索引。 如果您只想按item索引,則必須自己添加該索引。 您的PK將按invoice排序,然后按invoice在多個記錄中相同的item排序。 雖然復合PK中的順序與唯一性實施無關,但它對訪問很重要。

在你的桌子上我會使用:

PRIMARY KEY id (invoice, item), INDEX (item)

要返回表索引信息,您可以使用:

SHOW INDEX FROM <table>;

請參閱: http//dev.mysql.com/doc/refman/5.0/en/show-index.html

要查看表信息:

SHOW CREATE TABLE <table>;

請參閱: http//dev.mysql.com/doc/refman/5.0/en/show-create-table.html

主鍵是索引,因此無需創建其他索引。 您可以在CREATE TABLE語法下找到有關它們的更多信息(這里插入的內容太多了):

http://dev.mysql.com/doc/refman/5.0/en/create-table.html

我對MySQL並不熟悉,但通常多列索引在索引的第一列上同樣有用,僅作為該列的索引。 對於單個列,多列索引變得不那么有用,列進一步顯示在索引中。

如果您將多列索引視為層次結構,則這有一定意義。 索引中的第一列是層次結構的根,因此搜索它只是掃描第一級的問題。 但是,為了掃描第二列,數據庫必須查找第一列中找到的每個唯一值的樹。 這可能足夠昂貴,大多數優化器都不會費心深入研究多列索引,而是選擇全表掃描。

例如,如果您有一個表格如下:

Col1 |Col2 |Col3
----------------
   A |   1 |   Z
   A |   2 |   Y
   A |   2 |   X
   B |   1 |   Z
   B |   2 |   X

假設您按順序在所有三列上都有索引,樹將看起來像這樣:

A
+-1
  +-Z
+-2
  +-X
  +-Y
B
+-1
  +-Z
+-2
  +-X

尋找Col1 ='A'很簡單:您只需要查看2個有序值。 但是,要解決col3 ='X',您必須查看4個較大存儲桶中的所有值,每個存儲桶都是單獨訂購的。

復合索引和復合主鍵之間存在差異。 如果您已定義了如下所示的復合索引

INDEX idx(invoice,item)  

如果基於item查詢並且需要添加單獨的索引,則索引將不起作用

INDEX itemidx(item)  

但是,如果您已經定義了如下所示的復合主鍵

PRIMARY KEY(invoice, item)  

如果基於item查詢並且不需要單獨的索引,則索引將起作用。

工作范例:

mysql>create table test ( col1 int(20), col2 int(20) ) primary key(col1,col2);
mysql>explain select * from test where col2 = 1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | test  | index | NULL          | PRIMARY | 8       | NULL |   10 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

Mysql自動為復合鍵創建索引。 根據您的查詢,您可能必須為組合鍵中的單個列創建單獨的索引。

如果您使用的是mysql工作台,則可以手動右鍵單擊架構並單擊編輯以查看有關該表的所有信息

如果您的查詢在 where 子句中使用了兩列,那么您不需要在復合主鍵中創建單獨的索引。

EXPLAIN SELECT * FROM `table` WHERE invoice = 1 and item = 1

如果您只想查詢第一列,您也可以

EXPLAIN SELECT * FROM `table` WHERE invoice = 1

但是,如果您想使用復合 PK 中的后續列 col2、col3 進行查詢,則需要在這些列上創建單獨的索引。 以下說明查詢顯示第二列沒有 MySQL 檢測到的可能鍵

EXPLAIN SELECT * FROM `table` WHERE item = 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM