我的mySQL查询是否尽可能高效?
我有一个mySQL查询,需要很长时间来处理。我正在查询一个与国家代码相关的IP范围的大表,以发现url\u click表中每个IP的原产国。(来自的IP数据库)hxxp://ip-to-country.webhosting.info/) 它工作得非常出色,尽管速度很慢 有没有更有效的方法来编写此查询 表和输出JPG:我的mySQL查询是否尽可能高效?,mysql,Mysql,我有一个mySQL查询,需要很长时间来处理。我正在查询一个与国家代码相关的IP范围的大表,以发现url\u click表中每个IP的原产国。(来自的IP数据库)hxxp://ip-to-country.webhosting.info/) 它工作得非常出色,尽管速度很慢 有没有更有效的方法来编写此查询 表和输出JPG: IP地址有一个树状结构,您在geo_IP表中的范围很可能尊重该结构 如果您的IP以193.167开始,那么您应该有一个索引来帮助您快速过滤geo_IP表,以便只操作与193.167
IP地址有一个树状结构,您在geo_IP表中的范围很可能尊重该结构 如果您的IP以193.167开始,那么您应该有一个索引来帮助您快速过滤geo_IP表,以便只操作与193.167子范围相关的行 我认为通过这种方法,您应该能够显著提高响应时间
我希望这将帮助您这让我有点担心。这会使
ip\u addr
列上的任何索引都无用。如果您有一种方法可以将信息全部以相同的格式放置,比如在将数据放入数据库之前将其转换为数字,这可能会有所帮助
除此之外,关于明智使用索引的标准建议也适用。您可能需要在
ipfrom
和ipto
和/或url\u id
列上建立索引。MySQL
不能像这样优化查询
您需要将ipo从ipto
范围转换为LineStrings
,从而允许在其上构建R-Tree
索引:
ALTER TABLE
geo_ip
ADD range LINESTRING;
UPDATE geo_ip
SET range = LINESTRING(POINT(-1, ipfrom), POINT(1, ipfrom));
ALTER TABLE
geo_ip
MODIFY range LINESTRING NOT NULL;
CREATE SPATIAL INDEX
sx_geoip_range
ON geo_ip (range);
SELECT ip_addr AS IP, geo_ip.ctry, COUNT(*)
FROM `admin_adfly`.`url_click`
JOIN admin_adfly.geo_ip
ON MBRContains
(
Point(0, INET_ATON (ip_addr)),
range
)
WHERE url_id = 165
GROUP BY
ip_addr
geo_ip
应该是一个MyISAM
表
有关更多详细信息,请参见此处:
SELECT S.IP_Addr, G.Ctry AS Country, S.Count
FROM (SELECT ip_addr, COUNT(ip_addr) AS Count
FROM admin_adfly.url_click
WHERE url_id = 165
GROUP BY ip_addr) AS S
JOIN admin_adfly.geo_ip AS G
ON INET_ATON (ip_addr) BETWEEN geo_ip.ipfrom AND geo_ip.ipto;
如果您可以重新设计模式,并且要进行大量的分析,那么可以重新编写两个表中的一个,这样连接条件就不需要使用INET_ATON()
大概,您在
url\u id
列上有一个索引;这是唯一一个能给您带来很多好处的方法。我可以推荐这种方法吗?我怀疑在列的INET\u ATON()
上过滤结果意味着它必须扫描表,将INET\u ATON()
应用于url\u id=165
的所有内容-您能预处理INET\u ATON()吗
您的地址是否以某种方式作为一列?另外,你有关于url\u id的索引吗?另外,如果你让MySQL解释查询,你会得到什么?谢谢大家。我尝试了Quassnoi关于创建索引的建议,但由于某种原因,我无法创建b树存储类型。然后我尝试了Jonathan Leffler的建议,这确实缩短了查询的时间,但仍然花费了太长的时间。我决定在初始记录输入点查询与IP相关的国家,而不是在查询后查询。
SELECT S.IP_Addr, G.Ctry AS Country, S.Count
FROM (SELECT ip_addr, COUNT(ip_addr) AS Count
FROM admin_adfly.url_click
WHERE url_id = 165
GROUP BY ip_addr) AS S
JOIN admin_adfly.geo_ip AS G
ON INET_ATON (ip_addr) BETWEEN geo_ip.ipfrom AND geo_ip.ipto;