假设有一张行政区划表:
type Division struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Province string `gorm:"type:varchar(32);not null"`
Prefecture string `gorm:"type:varchar(32);not null"`
County string `gorm:"type:varchar(32);not null"`
}
查询省列表:
pros := make([]string, 0)
db.Model(&model.Division{}).Distinct().Pluck("province", &pros)
SELECT DISTINCT `province` FROM `divisions` WHERE `divisions`.`deleted_at` IS NULL
[
"北京市",
"天津市",
"河北省",
"山西省",
"内蒙古自治区",
"辽宁省",
"吉林省",
"黑龙江省",
"上海市",
"江苏省",
"浙江省",
"安徽省",
"福建省",
"江西省",
"山东省",
"河南省",
"湖北省",
"湖南省",
"广东省",
"广西壮族自治区",
"海南省",
"重庆市",
"四川省",
"贵州省",
"云南省",
"西藏自治区",
"陕西省",
"甘肃省",
"青海省",
"宁夏回族自治区",
"新疆维吾尔自治区",
"香港特别行政区",
"澳门特别行政区",
"台湾省"
]
现在给Province
字段加个索引:
Province string `gorm:"type:varchar(32);not null;index"`
再执行上述查询:
[
"上海市",
"云南省",
"内蒙古自治区",
"北京市",
"台湾省",
"吉林省",
"四川省",
"天津市",
"宁夏回族自治区",
"安徽省",
"山东省",
"山西省",
"广东省",
"广西壮族自治区",
"新疆维吾尔自治区",
"江苏省",
"江西省",
"河北省",
"河南省",
"浙江省",
"海南省",
"湖北省",
"湖南省",
"澳门特别行政区",
"甘肃省",
"福建省",
"西藏自治区",
"贵州省",
"辽宁省",
"重庆市",
"陕西省",
"青海省",
"香港特别行政区",
"黑龙江省"
]
排序规则变了,不再按照主键生序。
为什么索引会影响排序?
SQL 标准在没有
ORDER BY
的时候,确实没有指定排序的顺序的,因此实际排序是由数据库系统和底层的存储引擎来决定的。以 MySQL 为例,一般我们使用的
InnoDB
存储引擎,默认不指定排序条件时,因为 InnoDB 的 B+ 树结构,查询结果是从用到的树结构中,从左侧到右侧依次取值的,所以最终结果是按照查询用到的索引顺序的。当没有匹配的二级索引时,用到的是主键索引,所以结果按照主键排序,当用到其它二级索引时,则会按照用到的索引进行排序。