我有一张包含最小和最大字段的表格。该表填充了200条记录,这些记录都包含这些最小值和最大值的范围。我需要确定给定值是否在这些范围之一。
示例
min | max
21 | 34
64 | 83
112 | 134
给定值:36。在这种情况下,查询不应该找到任何内容。
当然,我可以遍历每个记录并查询值是否在这些值之间,但查询每分钟运行几次,所以我想知道如何优化它。
答案 0 :(得分:2)
这就是RDBMS的工作方式 - 它遍历行。现代数据库实际上没有200条记录。
无论如何要优化它,您应该在这些列上创建索引。 两个列上的一个索引。
然后,如下所示的简单查询将使用此索引,即使有很多行也能非常快速地工作。
SELECT * from table where 36 between min and max;
答案 1 :(得分:0)
在最小和最大列上创建索引应该可以提高性能
答案 2 :(得分:0)
Between运算符可以满足您的需求:
SELECT * FROM table WHERE 36 BETWEEN min AND max;
答案 3 :(得分:0)
两列的索引都没有特别的帮助。您要查找的查询是:
select *
from minmax
where "min" <= 36 and "max" >= 36;
不幸的是,这有两个不平等;一个指数实际上只能利用其中一个不等式。因此,在索引中"max"
确实有点帮助,但这只是因为索引“覆盖”了查询。也就是说,索引可用于处理查询,而不参考原始数据页。
但是,表中只有200行,处理并不是特别麻烦。如果您想知道表中是否存在某些内容,我建议您使用此查询:
select (case when exists (select 1 from minmax where "min" <= 36 and "max" >= 36)
then 1
else 0
end)
我的猜测是,在这样一个小桌子上的表现与minmax(min)
或minmax(min, max)
上的索引几乎相同。对于大型表,复合索引会更好。
答案 4 :(得分:0)
这与GeoIP table join with table of IP's in MySQL非常相似。人们通常在MySQL表中查找GeoIP信息,最快的方法是使用Spatial索引。
基本思路是使用包含表中最小值和最大值的数据创建多边形,然后向此字段添加空间索引。最后使用MBRCONTAINS()
,您可以非常快速有效地查看某个点是否在集合中。
以下文章介绍了如何执行此操作:http://blog.jcole.us/2007/11/24/on-efficiently-geo-referencing-ips-with-maxmind-geoip-and-mysql-gis/
基本思想是创建一个像:
这样的多边形SET poly = GEOMFROMWKB(POLYGON(LINESTRING(
POINT(min,-1),
POINT(max,-1),
POINT(max,1),
POINT(min,1),
POINT(min,-1)
)));
然后查找使用
SELECT id
FROM your_table
WHERE MBRCONTAINS(ip_poly, POINTFROMWKB(POINT([SEARCH_NUMBER], 0)))