我的mySQL查询是否尽可能高效?

我的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

我有一个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\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;