优化查询以确定值介于最小值和最大值之间

时间:2014-03-25 13:05:24

标签: php mysql

我有一张包含最小和最大字段的表格。该表填充了200条记录,这些记录都包含这些最小值和最大值的范围。我需要确定给定值是否在这些范围之一。

示例

min | max    
21  | 34    
64  | 83    
112 | 134

给定值:36。在这种情况下,查询不应该找到任何内容。

当然,我可以遍历每个记录并查询值是否在这些值之间,但查询每分钟运行几次,所以我想知道如何优化它。

5 个答案:

答案 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)))