[英]mysql query optimization - indexes
我有3表的数据库。
CREATE TABLE `records` (
`id` int(6) NOT NULL auto_increment,
`nu` varchar(40) NOT NULL UNIQUE,
`name` varchar(128),
`latitude` float NOT NULL,
`longitude` float NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `categories` (
`category_id` int(11) NOT NULL,
`category_label` varchar(100) NOT NULL UNIQUE,
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `relational` (
`r_id` int(6) NOT NULL auto_increment,
`id` int(6) NOT NULL,
`category_id` int(11) NOT NULL auto_increment,
PRIMARY KEY (`r_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我也有2个外键,category_id和id。
我也为category_label和纬度做了索引。 我已经这样查询了
SELECT id, name, latitude, longitude, category_label, ( 6371 * acos( cos(
radians('$lat') ) * cos( radians( latitude ) ) * cos( radians( longitude ) -
radians('$lng') ) + sin( radians('$lat') ) * sin( radians( latitude ) ) ) )
AS distance, FROM records JOIN relational ON records.id = relational.id
JOIN categories ON relational.category_id = categories.category_id
WHERE category_label = '$label' GROUP BY distance HAVING (distance <=
'$radius') ORDER BY distance
我的问题是我有一个很大的数据库,查询运行时间太长。 我应该为此查询使用哪些索引。 实际上,我不知道拥有索引可以帮助我解决距离问题的正确方法。 我应该改变索引吗? 如何改善数据库结构或查询? 我正在使用InnoDB。
首先,你应该看看这个和这个 -我强烈建议使用它,而不是在你的情况下,通用的数据类型的。
就当前的架构而言,请考虑在relational.id
和relational.category_id
(2个独立的索引)上添加索引。 但这从长远来看也无济于事。 其他有用的方法-无需即时计算distance
-将其缓存在另一个表中,例如,您可以在其中建立索引:查询中最昂贵的部分之一是对动态分组和后过滤(因此, )栏位
而且,您实际上并不需要为categories.category_label
另一个索引-您已经对其具有UNIQUE约束,这意味着需要建立索引。
您还可以在records
表上创建覆盖索引,但是与修复动态字段操作相比,它没有太大的帮助
为了帮助您入门categories
,请添加INDEX(category_label)
relational
看起来像“多对多”映射。 “记录”是否在多个“类别”中,并且每个“类别”都有许多“记录”? 如果是这样,则需要多对多。 为了提高性能,请遵循此处的提示。
然后...
改进距离搜索的快速简便方法是在WHERE
子句中使用“边界框”,并使用INDEX(latitude), INDEX(longitude)
。
如果nu
是UNIQUE
,那么您可能应该将其作为PRIMARY KEY
并删除id
。 (首先更改“ Relational
。)
下一个问题是过滤( WHERE
)进入了两个表(用于按类别和位置进行过滤)。 这样无法优化。 取而代之的是,希望查询可以在一个表上进行有效过滤,然后在查找另一表时对其进行进一步优化。
Google空间索引。 它是几何数据的2D索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.