2011-08-31 115 views
12

我有一个MySQL数据库如下表:多列索引VS多个索引

CREATE TABLE `secondary_images` (
    `imgId` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `primaryId` int(10) unsigned DEFAULT NULL, 
    `view` varchar(255) DEFAULT NULL, 
    `imgURL` varchar(255) DEFAULT NULL, 
    `imgDate` datetime DEFAULT NULL, 
    PRIMARY KEY (`imgId`), 
    KEY `primaryId` (`primaryId`), 
    KEY `imgDate` (`imgDate`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; 

的SQL将是以下几点:

SELECT imgURL, view FROM secondary_images 
WHERE primaryId={$imgId} ORDER BY imgDate DESC 

正如你可以看到我做了两个primaryIdimgDate,索引键。我背后的想法是因为WHERE子句的查询结果使用primaryIdORDER子句使用imgDate

我的问题是,它会更好,因为我现在使用多个索引?或者我应该多列索引(目前我不太了解的东西)?

这是我从得到解释一下:

id = 1 
select_type = simple  
table = secondary_images   
type = ref 
possible_keys = primaryId 
key = primaryId 
key_len = 5 
ref = const 
rows = 1 
extra = Using where; Using filesort 

注:这不是使用多列索引,它是从使用上表中描述的结果。

+0

你可以发布EXPLAIN的选择? :) – Konerak

+2

请记住,indeces不是免费的。如果您有多个indeces,这意味着每次插入或更新时,都需要更新每个索引。您需要权衡这些更新的性能点击与您在检索时看到的性能改进。 – Marvo

+0

还请记住,如果您有许多行中具有相同值的列,则索引可能实际上会使性能变差。 – Poodlehat

回答

13

您应该使用上(primaryId,imgDate)多列索引,使MySQL是可以用它来选择行和排序。

如果用于排序的所有列不是用于选择的索引,MySQL使用“文件排序”战略,即由排序的所有行(在内存中的,如果没有太多的行;在磁盘上的其他人)。

如果用于排序的所有列索引,MySQL使用索引来获取行的次序(有一些限制)。

MySQL为索引使用树结构。这允许直接访问密钥而不需要排序。

阿多列索引基本上是列连接的索引。这允许MySQL找到匹配primaryId={$imgId}的第一行,然后直接以正确的顺序访问所有其他行。

随着primaryId单列索引,MySQL能够找到匹配primaryId={$imgId}的所有行,但它会在没有特定的顺序找到行;所以它必须在那之后对它们进行排序。

EXPLAINORDER BY Optimization

+0

我不明白为什么 - 它将一列与另一列进行比较,而不是将两列同时对另外两列进行比较。你可以解释吗? – Poodlehat

+0

@ arnaud576875 - 非常感谢!你有什么机会给我一个简要的解释,说明为什么在这种情况下这是最好的选择?另外,我将如何使用'SQL'在'(primaryId,imgDate)'上使用多列索引来更改当前表? – stefmikhail

+0

@Poodlehat,stefmikhail我已经更新了答案 – arnaud576875

11

你解释这个样子的:

[id] => 1 
[select_type] => SIMPLE 
[table] => secondary_images 
[type] => ref 
[possible_keys] => primaryId 
[key] => primaryId 
[key_len] => 5 
[ref] => const 
[rows] => 1 
[Extra] => Using where; Using filesort 

让我们看它。

[id] => 1 

表示我们正在讨论第一张表。你只是在你的陈述中调用一张表。

[select_type] => SIMPLE 

我们正在做一个简单的SELECT。

[table] => secondary_images 

有问题的表名。

[type] => ref 

选择类型,对于连接最重要。

[possible_keys] => primaryId 

这是一个重要领域:它示出了密钥可能被用于帮助查询在执行速度更快。在这种情况下,只有您的主键被认为是有用的。

[key] => primaryId 

这是一个重要领域:它示出了最后被用于哪个键(一个或多个)。在这种情况下,主键。

[key_len] => 5 
[ref] => const 
[rows] => 1 

猜测查询检查的行数。

[Extra] => Using where; Using filesort 

最重要的领域恕我直言。 - 使用where:您正在使用where语句。很好。 - 使用filesort:您的查询结果如此之大,不能在内存中排序 。 MySQL必须将其写入文件,对文件进行排序,然后输出。这意味着磁盘访问,并会放慢一切。 添加一个可以帮助排序的索引通常会有所帮助,但是解决 “使用filesort”本身就是一章。

+0

哇,哇哇。非常感谢你。这很容易理解。那么,如何使用这些信息来决定是否需要多重索引键呢?我不会要求你进入filesort问题,因为你自己说这完全是另一个问题,但是会切换到多索引键帮助吗? – stefmikhail

+2

你应该首先**阅读关于解释。 MySQL网站是一个很好的开始,“高性能MySQL”是我读过的最好的MySQL书籍。然后,了解它非常依赖于您的表,存储引擎,配置(缓存大小等)以及表中的数据。因此,测试的最佳方式是:复制表格,并在副本上添加所需的索引。然后,比较说明。这就是为什么你需要理解解释:) – Konerak

+0

再次感谢。非常感激。我会拿起那本书。 – stefmikhail