多列索引与多个索引

ste*_*ail 13 mysql database indexing database-design query-optimization

我在MySQL数据库中有下表:

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 ;
Run Code Online (Sandbox Code Playgroud)

SQL将如下:

SELECT imgURL, view FROM secondary_images 
WHERE primaryId={$imgId} ORDER BY imgDate DESC
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我创建了primaryIdimgDate索引键.我背后的想法是因为该WHERE子句使用the primaryIdORDER子句使用查询结果imgDate.

我的问题是,现在使用多重索引会更好吗?或者我应该选择多列索引(目前我还不太了解)?

这是我从EXPLAIN得到的:

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
Run Code Online (Sandbox Code Playgroud)

注意:这不是使用多列索引,而是使用上表描述的结果.

Arn*_*anc 14

您应该在(primaryId,imgDate)上使用多列索引,以便MySQL能够使用它来选择行和排序.

如果用于排序的所有列都不在用于选择的索引中,则MySQL使用" filesort "策略,该策略包括对所有行进行排序(如果没有太多行,则在内存中;在磁盘上).

如果用于排序的所有列都在索引中,MySQL使用索引来获取行顺序(有一些限制).

MySQL使用树结构作为索引.这允许直接访问键而无需排序.

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

在单行索引打开的情况下primaryId,MySQL可以找到匹配的所有行primaryId={$imgId},但它会找到没有特定顺序的行; 所以它必须在那之后对它们进行排序.

请参阅EXPLAINORDER BY Optimization.


Kon*_*rak 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 
Run Code Online (Sandbox Code Playgroud)

让我们来看看吧.

[id] => 1 
Run Code Online (Sandbox Code Playgroud)

意味着我们正在谈论第一张桌子.您只在声明中调用一个表.

[select_type] => SIMPLE 
Run Code Online (Sandbox Code Playgroud)

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

[table] => secondary_images 
Run Code Online (Sandbox Code Playgroud)

有问题的表名.

[type] => ref 
Run Code Online (Sandbox Code Playgroud)

选择类型,对连接最重要.

[possible_keys] => primaryId 
Run Code Online (Sandbox Code Playgroud)

这是一个重要的字段:它显示了可以使用哪些键来帮助查询执行得更快.在这种情况下,只有您的主键被认为是有用的.

[key] => primaryId 
Run Code Online (Sandbox Code Playgroud)

这是一个重要的领域:它显示最终使用了哪些密钥.在这种情况下,主键.

[key_len] => 5 
[ref] => const 
[rows] => 1 
Run Code Online (Sandbox Code Playgroud)

猜测查询检查的行数.

[Extra] => Using where; Using filesort 
Run Code Online (Sandbox Code Playgroud)

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

  • 你应该**首先**阅读解释.MySQL站点是一个很好的起点,"高性能MySQL"是我读过的最好的MySQL书籍.然后,了解它在很大程度上取决于您的表,存储引擎,您的配置(缓存大小等)以及表中的数据.因此,最好的测试方法是:复制表格,并在副本上添加所需的索引.然后,比较解释.这就是为什么你需要了解解释:) (2认同)