Sql 索引和多列主键

Sql 索引和多列主键,sql,mysql,primary-key,indexing,Sql,Mysql,Primary Key,Indexing,进行了搜索,但没有找到这个特定noob问题的答案。如果我错过了,我道歉 在MySQL数据库中,我有一个具有以下主键的表 主键id(发票、项目) 在我的应用程序中,我也会经常自己选择“项目”,而较少选择“发票”。我假设我会从这些列的索引中受益 当我定义以下内容时,MySQL不会抱怨: 索引(发票), 索引(项目), 主键id(发票、项目) 但我没有看到任何证据(使用descripe——我知道的唯一方法)表明这两列已经建立了单独的索引 所以问题是,组成主键的列是否会自动单独索引?此外,还有比“描述”

进行了搜索,但没有找到这个特定noob问题的答案。如果我错过了,我道歉

在MySQL数据库中,我有一个具有以下主键的表

主键id(发票、项目)

在我的应用程序中,我也会经常自己选择“项目”,而较少选择“发票”。我假设我会从这些列的索引中受益

当我定义以下内容时,MySQL不会抱怨:

索引(发票), 索引(项目), 主键id(发票、项目)

但我没有看到任何证据(使用descripe——我知道的唯一方法)表明这两列已经建立了单独的索引


所以问题是,组成主键的列是否会自动单独索引?此外,还有比“描述”更好的方法来探索我的表的结构吗?

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

SHOW INDEX FROM <table>;
显示来自的索引;
见:

要查看表格信息,请执行以下操作:

SHOW CREATE TABLE <table>;
显示创建表;
见:

主键是索引,因此不需要创建额外的索引。您可以在
CREATE TABLE
语法下找到关于它们的更多信息(此处插入的内容太多):


我对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个较大存储桶中的所有值,每个存储桶都是单独排序的。

我个人用来查看和编辑MySQL数据库的结构。它是一个web应用程序,但在本地web服务器上运行得足够好(为此和phpPgAdmin,我在机器上运行了一个apache实例)

对于
(发票,项目)
的复合键,它充当
(发票,项目)
发票
的索引。如果您只想通过
建立索引,您必须自己添加该索引。您的主键将按
发票
排序,然后按
项目
排序,其中
发票
在多条记录中相同。虽然复合PK中的顺序与唯一性强制无关,但与访问无关

在您的桌子上,我将使用:

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

我不太熟悉mySql上索引的内部结构,但在我熟悉的两个数据库供应商产品(MsSQL、Oracle)上,索引是平衡的树结构,其节点被组织为索引所定义的列的序列元组(按照定义的序列

因此,除非mySql做得非常不同,(可能不是),任何需要按索引中列的子集进行过滤或排序的查询都可以使用任何复合索引(在多个列上),只要列列表兼容,即,如果列,当按与完整索引中列的顺序列表相同的顺序排列时,是完整索引列集合的有序子集,它从实际索引序列的开头开始,除了结尾之外没有间隙

换句话说,这意味着如果您在(a,b,c,d)上有索引,则筛选(a)、(a,b)或(a,b,c)的查询也可以使用该索引,但需要筛选(b)、或(c)或(b,c)的查询将无法使用该索引


因此,在您的情况下,如果您经常需要单独对列进行筛选或排序,则需要在该列上单独添加另一个索引

复合指数和复合主键之间存在差异。 如果您定义了如下所示的复合索引

INDEX idx(invoice,item)  
如果基于
项进行查询,并且需要添加单独的索引,则索引将不起作用

INDEX itemidx(item)  
但是,如果您定义了如下所示的复合主键

PRIMARY KEY(invoice, 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 workbench,您可以手动右键单击模式,然后单击edit查看表的所有内容

谢谢大家。像往常一样,来自一个非常慷慨的社区的大量信息。答案似乎集中在排序和选择上。对于选择,索引是否同样重要?我将使用返回1到10行的select语句。在我的情况下,顺序真的不重要。当查询返回几行时,索引对于选择更为重要,而当查询返回多行时,索引对于排序更为重要。。。对10行进行排序很简单。很难找到它们。如果查询返回整个表(或其中很大一部分),那么查找行并不是问题,但对大型结果集进行排序是…感谢您提供的信息以及清晰易懂的答案,您为我节省了很多时间:)这应该被选为答案,因为它解释了多主键与索引和u一样使用