【发布时间】:2014-11-06 22:30:18
【问题描述】:
我的关系有点奇怪,但一定是这样:
SELECT COUNT(DISTINCT `t`.`id`)
FROM `radcliente` `t`
LEFT OUTER JOIN `radcliente_endereco_instalacao` `endereco_instalacao`
ON (`endereco_instalacao`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_telefone` `telefones`
ON (`telefones`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_email` `emails`
ON (`emails`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radmetodo_cobranca` `metodo_cobranca`
ON (`metodo_cobranca`.`cliente_id`=`t`.`id`) AND (metodo_cobranca.arquivo = 'nao')
LEFT OUTER JOIN `radacct` `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
AND (ultimo_acct.radacctid = (
SELECT `radacctid` FROM
(SELECT radacctid
FROM `radacct` `fUzDDUDv`
WHERE username = t.login
) AS `fUzDDUDv` ORDER BY `radacctid` DESC LIMIT 1
)
)
WHERE (ultimo_acct.framedipaddress = '177.23.209.194')
“where 子句”中的未知列“t.login”。
更新:
是的,这可以解决问题。我创建了这个子查询,为什么我使用 Yii 框架,并且 has_one 关系没有限制,即如果一个“客户”有数百万个“账户”,框架会寻找所有“账户”,只取一个这给一些 GB 的流量,而且非常慢。为了解决,我使用子查询仅寻找最新的 id 来获取“客户”和最后一个“账户”并使其在 Active Record 中工作,直到那时一切都很好,但搜索速度很慢,寻找记录需要 40秒,然后我发现问题出在'ORDER BY'(radacctid是索引,表是innodb),因此我确实解决了子查询之外的'ORDER BY',然后解决了子查询列的问题表 'cliente' (t.login) 就像我上面解释的那样。
我也尝试过按另一个字段排序,例如“acctstarttime”,并且继续缓慢,只有当我这样做时才解决:
SELECT `radacctid` FROM
(SELECT radacctid
FROM `radacct` `fUzDDUDv`
WHERE username = t.login
) AS `fUzDDUDv` ORDER BY `radacctid` DESC LIMIT 1
更新:
但是INNER JOIN的问题是如果'acct'没有结果就不会返回'cliente'。
更新
问题不在于t.login 的位置,但它不被识别为存在于子查询中,如果订单不慢,我无法“输出”。
更新
读我的cmets?这是这种情况。它真的只在生产服务器上一直有插入和更新。
【问题讨论】:
-
很抱歉没有直接解决这个问题:我在您的陈述中看到一件事,我们在使用 ERP 数据库时遇到了很多问题。这涉及到主要的、最顶层的 SQL 语句的 WHERE 部分。您在 WHERE 子句中使用
(ultimo_acct.framedipaddress = '177.23.209.194')而ultimo_acct是一个表“左连接”到您的基本查询集 - 据我所知,这种比较将导致您的查询将ultimo_acct视为它在哪里 INNER-JOINED。 -
据我所知,mysql 可能无法在您的原始子查询中识别
t.login,因为它相对于t表所在的顶级查询嵌套了一层太多。而不是(ultimo_acct.radacctid = (SELECT radacctid FROM (SELECT radacctid FROM radacct fUzDDUDv WHERE username = t.login) AS fUzDDUDv ORDER BY radacctid DESC LIMIT 1),使用(ultimo_acct.radacctid = (SELECT fUzDDUDv.radacctid FROM radacct fUzDDUDv WHERE fUzDDUDv.username = t.login ORDER BY fUzDDUDv.radacctid DESC LIMIT 1))就足够了,据我所知,通过这种修改mysql不应该给出错误 -
是的,这行得通,但是'ORDER BY'太慢了。
-
如果我理解得很好,
(SELECT fUzDDUDv.radacctid FROM radacct fUzDDUDv WHERE fUzDDUDv.username = t.login ORDER BY fUzDDUDv.radacctid DESC LIMIT 1))部分会减慢整个查询的速度,你猜? -
绝对确定,但只有在与 WHERE 一起使用时才会减慢,例如,如果您只停留在 ORDER BY 'phpmyadmin' 中,并不慢(0.0007)并且仅在没有 ORDER BY 和 LIKE 的情况下使用 WHERE(0.0019) ,并记住 t.login fUzDDUDv .username 是索引。我相信这就是为什么查询结果的数量很大的原因似乎也很快,它在使用“排序”的“发送数据”处暂停。相信其他服务器在本地提供相同的东西更快,因为没有“查询”到所有 momendo the Freeradius。