通过php计算行数比SQL中的计算快?
简言之,我的问题是:这是为什么 从'base'中选择r.x,r.y作为r 其中r.l=50,r.n'name'和6=从环绕中选择计数*作为d通过php计算行数比SQL中的计算快?,php,mysql,sql,Php,Mysql,Sql,简言之,我的问题是:这是为什么 从'base'中选择r.x,r.y作为r 其中r.l=50,r.n'name'和6=从环绕中选择计数*作为d 其中,d.x>=r.x-1和d.x=r.y-1和d.y您正在自己连接两个表。你是一个优化器。选择“基”表是嵌套循环联接的外部表。我猜MySQL的优化器产生了执行计划,它和您不一样 所以人们希望解释输出以查看连接顺序并检查索引的使用情况 顺便问一下,你能试试这个查询吗 SELECT r.x, r.y FROM `base` AS r, surround AS
其中,d.x>=r.x-1和d.x=r.y-1和d.y您正在自己连接两个表。你是一个优化器。选择“基”表是嵌套循环联接的外部表。我猜MySQL的优化器产生了执行计划,它和您不一样 所以人们希望解释输出以查看连接顺序并检查索引的使用情况 顺便问一下,你能试试这个查询吗
SELECT r.x, r.y
FROM `base` AS r, surround AS d
WHERE r.l=50
AND r.n<>'name'
AND d.x >= r.x -1
AND d.x <= r.x +1
AND d.y>=r.y -1
AND d.y<=r.y +1
AND d.n='name'
GROUP BY r.x, r.y
HAVING COUNT(*) = 6
更新
原始查询的工作方式
这是第一次看到为每个记录索引映射检查范围:0x1,所以我无法理解您的查询是如何工作的。给我们一些关于它的信息。好像环绕中的每一行都有57k行?是比较基数的x,y。如果是这样,则使用3深度嵌套循环联接来计算查询。base=>surround=>base,而且会比较surround中的每一行,这是低效的
我以后会更努力地去发现它是如何工作的。是时候开始工作了。这很可能与索引的使用方式有关。最好做一个解释sql并在这里发布这三条语句。我认为使用查询会更快。最后,您将获得一个MYSQL结果集,并将通过PHP进行计数。我希望数据库对记录进行计数,并提供计数,因为这不是一个繁重的事务。name字段是否在两个表中都建立了索引?n name字段没有在表中建立索引,我补充说,出于测试目的,但这不会导致加载时间的变化。除bid外,所有字段本身都不是唯一的,但我并没有真正使用该字段,只有x和y的组合是唯一的,所以我选择了这个键。在PHP版本中,您缺少d.n='name'。您在加入时做了一些困难的事情,这就是我开始整个查询的原因,通过尝试找出合适的连接,但最终找到了这个。因此,我在原始帖子中添加了解释,并没有告诉我太多,但是您的查询工作得很好,非常快,0.15秒,并且给出了与php查询和原始慢速查询相同的结果。谢谢!PHP版本中的d.n='name'位于subquery@rolfv1很高兴看到你的评论。这让我很高兴;-但很抱歉没有给出解释输出的确切答案。
CREATE TABLE IF NOT EXISTS `base` (
`bid` int(12) NOT NULL COMMENT 'Base ID',
`n` varchar(25) NOT NULL COMMENT 'Name',
`l` int(3) NOT NULL,
`x` int(3) NOT NULL,
`y` int(3) NOT NULL,
`LastModified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `coord` (`x`,`y`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `surround` (
`bid` int(12) NOT NULL COMMENT 'Base ID',
`n` varchar(25) NOT NULL COMMENT 'Name',
`l` int(3) NOT NULL,
`x` int(3) NOT NULL,
`y` int(3) NOT NULL,
`LastModified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `coord` (`x`,`y`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY r range coord,n coord 4 NULL 4998 Using where
2 DEPENDENT SUBQUERY d ALL coord NULL NULL NULL 57241 Range checked for each record (index map: 0x1)
SELECT r.x, r.y
FROM `base` AS r, surround AS d
WHERE r.l=50
AND r.n<>'name'
AND d.x >= r.x -1
AND d.x <= r.x +1
AND d.y>=r.y -1
AND d.y<=r.y +1
AND d.n='name'
GROUP BY r.x, r.y
HAVING COUNT(*) = 6