【发布时间】:2019-03-06 19:34:48
【问题描述】:
表格
-
ip2country有 250k 行(通过 from_ip 升序插入的 ip 范围) -
sessions有 50 行
明显而缓慢(2.687 秒):
SELECT
s.*,
ip.country
FROM
sessions s
JOIN ip2country ip ON s.ip_addr BETWEEN ip.from_ip AND ip.to_ip
虽然这本身很快(0.031 秒):
SELECT
*
FROM
ip2country
WHERE
from_ip >= 387703808
LIMIT 1
所以基本上问题归结为能够在连接表中使用 LIMIT。可以做到这一点,它会是什么样子? (MySQL 5.7.24)
【问题讨论】:
-
你为什么要这样做?
-
LIMIT 在表扫描后完成。它不会有任何实际效果。您的表中是否设置了正确的索引?尝试在第一条语句上使用 EXPLAIN
-
是的,索引在那里,但它们根本没有帮助。解释看起来不太好:( 1 SIMPLE s ALL ip_addr 48 100.00 1 SIMPLE ip ALL to_ip,from_ip 248160 11.11 检查每条记录的范围(索引图:0x6)
-
嗯,这看起来不太好:stackoverflow.com/questions/8195304/…
-
非常糟糕:mariadb.com/kb/en/library/ip-range-table-performance。看起来我坚持在插入过程中使用来自 ip2country 的 PK 在会话表中添加“geo”列和标记记录。确实是一个悲伤但快速且最不复杂的“解决方案”。