gpt4 book ai didi

mysql - 什么时候应该使用复合索引?

转载 作者:行者123 更新时间:2023-11-30 21:32:11 24 4
gpt4 key购买 nike

  1. 什么时候应该在数据库中使用复合索引?
  2. 使用综合指数)?
  3. 为什么要使用复合索引?

例如,我有一个homes表:

CREATE TABLE IF NOT EXISTS `homes` (
`home_id` int(10) unsigned NOT NULL auto_increment,
`sqft` smallint(5) unsigned NOT NULL,
`year_built` smallint(5) unsigned NOT NULL,
`geolat` decimal(10,6) default NULL,
`geolng` decimal(10,6) default NULL,
PRIMARY KEY (`home_id`),
KEY `geolat` (`geolat`),
KEY `geolng` (`geolng`),
) ENGINE=InnoDB ;

我对 geolatgeolng 使用复合索引是否有意义,这样:

我替换:

  KEY `geolat` (`geolat`),
KEY `geolng` (`geolng`),

与:

KEY `geolat_geolng` (`geolat`, `geolng`)

如果是:

  • 为什么?
  • 使用复合索引对性能有何影响?

更新:

由于很多人都说它完全取决于我执行的查询,下面是执行的最常见的查询:

SELECT * FROM homes
WHERE geolat BETWEEN ??? AND ???
AND geolng BETWEEN ??? AND ???

更新 2:

使用以下数据库模式:

CREATE TABLE IF NOT EXISTS `homes` (
`home_id` int(10) unsigned NOT NULL auto_increment,
`primary_photo_group_id` int(10) unsigned NOT NULL default '0',
`customer_id` bigint(20) unsigned NOT NULL,
`account_type_id` int(11) NOT NULL,
`address` varchar(128) collate utf8_unicode_ci NOT NULL,
`city` varchar(64) collate utf8_unicode_ci NOT NULL,
`state` varchar(2) collate utf8_unicode_ci NOT NULL,
`zip` mediumint(8) unsigned NOT NULL,
`price` mediumint(8) unsigned NOT NULL,
`sqft` smallint(5) unsigned NOT NULL,
`year_built` smallint(5) unsigned NOT NULL,
`num_of_beds` tinyint(3) unsigned NOT NULL,
`num_of_baths` decimal(3,1) unsigned NOT NULL,
`num_of_floors` tinyint(3) unsigned NOT NULL,
`description` text collate utf8_unicode_ci,
`geolat` decimal(10,6) default NULL,
`geolng` decimal(10,6) default NULL,
`display_status` tinyint(1) NOT NULL,
`date_listed` timestamp NOT NULL default CURRENT_TIMESTAMP,
`contact_email` varchar(100) collate utf8_unicode_ci NOT NULL,
`contact_phone_number` varchar(15) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`home_id`),
KEY `customer_id` (`customer_id`),
KEY `city` (`city`),
KEY `num_of_beds` (`num_of_beds`),
KEY `num_of_baths` (`num_of_baths`),
KEY `geolat` (`geolat`),
KEY `geolng` (`geolng`),
KEY `account_type_id` (`account_type_id`),
KEY `display_status` (`display_status`),
KEY `sqft` (`sqft`),
KEY `price` (`price`),
KEY `primary_photo_group_id` (`primary_photo_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=8 ;

使用以下 SQL:

EXPLAIN SELECT  homes.home_id,
address,
city,
state,
zip,
price,
sqft,
year_built,
account_type_id,
num_of_beds,
num_of_baths,
geolat,
geolng,
photo_id,
photo_url_dir
FROM homes
LEFT OUTER JOIN home_photos ON homes.home_id = home_photos.home_id
AND homes.primary_photo_group_id = home_photos.home_photo_group_id
AND home_photos.home_photo_type_id = 2
WHERE homes.display_status = true
AND homes.geolat BETWEEN -100 AND 100
AND homes.geolng BETWEEN -100 AND 100

解释返回:

id  select_type  table        type  possible_keys                                    key                  key_len  ref     rows  Extra
----------------------------------------------------------------------------------------------------------
1 SIMPLE homes ref geolat,geolng,display_status display_status 1 const 2 Using where
1 SIMPLE home_photos ref home_id,home_photo_type_id,home_photo_group_id home_photo_group_id 4 homes.primary_photo_group_id 4

我不太明白如何阅读 EXPLAIN 命令。这看起来是好是坏。现在,我没有使用 geolat 和 geolng 的复合索引。我应该吗?

最佳答案

当您使用从中受益的查询时,您应该使用复合索引。看起来像这样的复合索引:

index( column_A, column_B, column_C )

将有利于使用这些字段进行连接、过滤和有时选择的查询。它还将有利于使用该组合中列的最左侧子集的查询。所以上面的索引也会满足需要的查询

index( column_A, column_B, column_C )
index( column_A, column_B )
index( column_A )

但它不会(至少不会直接,如果没有更好的索引,它可能会部分帮助)帮助需要的查询

index( column_A, column_C )

注意 column_B 是如何丢失的。

在您的原始示例中,两个维度的复合索引将主要有利于查询两个维度或最左侧维度本身的查询,而不是最右侧维度本身。如果您总是查询两个维度,复合索引是可行的方法,哪个在第一个并不重要(最有可能)。

关于mysql - 什么时候应该使用复合索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55653798/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com