php - mysql查询优化——索引

标签 php mysql indexing latitude-longitude sql-optimization

我有一个包含 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。
我也为类别标签和纬度制作了索引。 我的查询是这样的

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。

最佳答案

首先,您可能应该看一下 thisthis - 我强烈建议在您的情况下使用它而不是常见的数据类型。

就您当前的架构而言,请考虑在 relational.idrelational.category_id(2 个单独的索引)上添加索引。但从长远来看,这也无济于事。其他有帮助的事情 - 不要即时计算距离 - 将其缓存在另一个表中,例如,您可以在其中索引它:查询中最昂贵的部分之一是分组和后处理对动态(因此慢)字段进行过滤

而且您实际上并不需要为 categories.category_label 建立另一个索引 - 您已经对它有了 UNIQUE 约束,这意味着索引。

您还可以在记录表上创建覆盖索引,但与修复动态字段操作相比,它不会带来太大的提升

关于php - mysql查询优化——索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46368330/

相关文章:

mysql - 每个指定组选择 n 个随机行

matlab - 在 MATLAB 中是否有一种矢量化方法可以对每列的不同数量的值进行操作?

php - 从 MySQL 到 PHP 页面选择数据时遇到问题

php - JS 表单元素的问题

mysql - SELECT alias 自动为表中的所有字段设置别名?

java - 为什么我的短语查询给我的结果这么少?

file - Web.xml:欢迎文件显示不正确

php - 正则表达式:如何修改组的内容

php - 拉拉维尔 8 : Trying to get property 'name' of non-object

mysql - 从硬编码列表 MySql 中查询