[英]Slow queries with MySQL large database
我有一个表ipaddresses
包含IP范围。 列为:ipStart,ipEnd
例子
ipStart: 3579374832
ipEnd: 3579374839
现在,我想从另一个表中选择visit_count
IP地址: visit_count
。 根据这300个地址,我想检查ip地址是否在表ipaddresses
的任何IP范围内
我当前的代码:
$results = $database->query("SELECT user_id,
DATE_FORMAT(last_visit, '%Y-%m-%d') as datumet,
cookieId, ipaddress
FROM `visit_count`
WHERE last_visit BETWEEN
'$firstDayOfMonth' AND '$lastDayOfMonth'
AND user_id = '$userId'
GROUP BY cookieId
ORDER BY last_visit ASC");
$rows = $database->loadObjectList($results);
foreach ( $rows as $row ) {
$ipaddressLong = ip2long($row->ipaddress);
// This is where its very very slow
$selO = $database->query("SELECT ipStart, ipEnd FROM `ipaddresses`
WHERE '$ipaddressLong' BETWEEN `ipStart` AND `ipEnd`");
$rowO = $database->getrow($selO);
}
结果是一个非常慢的查询,消耗了大量的cpu。
ipaddresses
具有ipStart
和ipEnd
索引,并包含约5万行。
我怎样才能使速度更快?
使用JOIN对单个查询进行快速而肮脏的更改:
SELECT a.ipStart, a.ipEnd
FROM `ipaddresses` a
INNER JOIN
(
SELECT user_id, DATE_FORMAT(last_visit, '%Y-%m-%d') as datumet, cookieId, inet_aton(ipaddress ) AS ipaddressLong
FROM `visit_count`
WHERE last_visit BETWEEN '$firstDayOfMonth' AND '$lastDayOfMonth'
AND user_id = '$userId'
GROUP BY cookieId
) b
ON b.ipaddressLong BETWEEN a.ipStart AND a.ipEnd
注意,这可能会简化。 但是,这取决于您对GROUP BY cookieId的使用 。 目前,每个cookie ID将获得一行,但未定义哪一行(即可以是该cookie ID附带的任何user_id,ip地址和最后访问日期)。
您可以简化第一选择。 您不需要选择ipaddress
之外的任何字段。 您也不需要订购或分组结果。 如果你想要独一无二的ipaddress
ES,只是用distinct
select distinct ipaddress
from visit_count
where last_visit between '$firstDayOfMonth' and '$lastDayOfMonth'
and user_id = '$userId'
即使第二张表有5万行,选择的内容似乎也不多。 在我的机器上,即使没有索引,也只需要一秒钟的时间。
如果你想反正简化它,你可以join
与两个表
select ipstart, ipend
from ipaddresses i
join visit_count v on inet_aton(v.ipaddress) between i.ipstart and i.ipend
where v.last_visit between '$firstDayOfMonth' and '$lastDayOfMonth'
and v.userid = '$userId'
1)使用更好的查询,像其他建议给您的
2)您是否为所需字段定义了索引?
3)不知道您使用的是mysql还是mysqli ...无论如何都使用比fetch_array更快的fetch_assoc
有了这三个技巧,你应该没事
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.