应该按哪个顺序(表列或查询)复合索引?

Posted

技术标签:

【中文标题】应该按哪个顺序(表列或查询)复合索引?【英文标题】:In which order(table column or query) composite index should made? 【发布时间】:2013-12-27 17:26:07 【问题描述】:

我有一个示例表,例如 -

CREATE TABLE `cdr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `dataPacketDownLink` bigint(20) DEFAULT NULL,
  `dataPacketUpLink` bigint(20) DEFAULT NULL,
  `dataPlanEndTime` datetime DEFAULT NULL,
  `dataPlanStartTime` datetime DEFAULT NULL,
  `dataVolumeDownLink` bigint(20) DEFAULT NULL,
  `dataVolumeUpLink` bigint(20) DEFAULT NULL,
  `dataplan` varchar(255) DEFAULT NULL,
  `dataplanType` varchar(255) DEFAULT NULL,
  `createdOn` datetime DEFAULT NULL,
  `deviceName` varchar(500) DEFAULT NULL,
  `duration` int(11) NOT NULL,
  `effectiveDuration` int(11) NOT NULL,
  `hour` tinyint(4) DEFAULT NULL,
  `eventDate` datetime DEFAULT NULL,
  `msisdn` bigint(20) DEFAULT NULL,
  `quarter` tinyint(4) DEFAULT NULL,
  `validDays` int(11) DEFAULT NULL,
  `dataLeft` bigint(20) DEFAULT NULL,
  `completedOn` datetime DEFAULT NULL,
  `evedate` date NOT NULL DEFAULT '0000-00-00',
  PRIMARY KEY (`id`,`evedate`),
  KEY `evedate_index` (`evedate`),
  KEY `eve_hour_index` (`evedate`,`hour`),
  KEY `eve_msisdn_index` (`evedate`,`msisdn`)
) ENGINE=MyISAM AUTO_INCREMENT=259341694 DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE  COLUMNS(evedate)
(PARTITION `START` VALUES LESS THAN ('2013-09-01') ENGINE = MyISAM,
 PARTITION p01 VALUES LESS THAN ('2013-09-08') ENGINE = MyISAM,
 PARTITION p02 VALUES LESS THAN ('2013-09-15') ENGINE = MyISAM,
 PARTITION p03 VALUES LESS THAN ('2013-09-22') ENGINE = MyISAM,
 PARTITION p04 VALUES LESS THAN ('2013-09-29') ENGINE = MyISAM,
 PARTITION p05 VALUES LESS THAN ('2013-10-06') ENGINE = MyISAM,
 PARTITION p06 VALUES LESS THAN ('2013-10-12') ENGINE = MyISAM,
 PARTITION p07 VALUES LESS THAN ('2013-10-19') ENGINE = MyISAM,
 PARTITION p08 VALUES LESS THAN ('2013-10-25') ENGINE = MyISAM,
 PARTITION p09 VALUES LESS THAN ('2013-10-31') ENGINE = MyISAM,
 PARTITION p10 VALUES LESS THAN (MAXVALUE) ENGINE = MyISAM) */

现在看看索引eve_hour_index(evedate,hour)和eve_msisdn_index(evedate,msisdn)的顺序。但我在最后声明了 evedate。

我在某处读到复合索引中的顺序很重要。那么是哪个顺序呢?查询中的顺序还是表中的顺序?

我是否必须将此复合索引重写为 eve_hour_index(hour,evedate) 和 eve_msisdn_index(msisdn,evedate)?

或者第一个是正确的?

谢谢。

【问题讨论】:

这取决于查询。索引用于优化查询,如果不查看查询,很难说哪个更好。例如,eventdate+hour 的顺序最适合这些查询:SELECT max( hour ) WHERE eventdate = XXXXSELECT ... ORDER BY eventdate, hour,而相反的 hour+eventdate 最适合:SELECT max( eventdate ) WHERE hour = XXXSELECT ... ORDER BY hour, eventdate 这很有帮助,意味着表中的排序与索引无关,选择查询中的顺序应该是正确的。我明白你的意思了吗? 【参考方案1】:

简而言之,列的索引对象包含该列的值,这些值已排序,以便可以快速找到给定值。对于复合索引,它是类似的,但复合索引中列的值是组合和排序的,因此涉及复合索引中所有列的任何查询要快得多。

请注意,如果您在列 A 和 B(按该顺序指定)上有一个复合索引,它将大大提高在 A 和 B 上都有条件的查询的速度,有助于加快只有条件的查询在 A 上,并且可能无助于加快仅在 B 上具有条件的查询。

【讨论】:

以上是关于应该按哪个顺序(表列或查询)复合索引?的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB通过许多参数过滤(复合索引与否)

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

关于MySQL复合索引的使用方法有哪些?