1

我需要搜索比实际更大的最接近的拨号代码。例如,最接近 33 的将是 331 或 332(如果 331 不存在)......所以它必须是 33xxxx,34 无效。

这 2 个查询有效,但速度太慢(250 毫秒/行):

SELECT Dialcode
FROM table
WHERE (Dialcode LIKE '$var%' AND Dialcode > '$var' AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

SELECT Dialcode
FROM table
WHERE (MATCH(Dialcode) AGAINST ('$var*' IN BOOLEAN MODE) AND Dialcode > '$var'
      AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

我的拨号代码是 PRIMARY KEY BIGINT(15)。

我这样做吗,它真的很快(> 1ms/行),但这并不是我所需要的:

SELECT Dialcode
FROM table
WHERE (Dialcode >= '$var' AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

所以我想我的问题是 LIKE / MATCH AGAINST。

任何想法,将不胜感激。

更新解决方案:

改编自raina77ow建议的解决方案:

SELECT Dialcode FROM table WHERE (( (Dialcode BETWEEN $var * 1 AND ’9’ )
   OR (Dialcode BETWEEN $var * 10 AND $var.’99’ )   
   OR (Dialcode BETWEEN $var * 100 AND $var.’999’ )
OR (Dialcode BETWEEN $var * 1000 AND $var.’9999’ )
…
) AND Price IS NOT NULL) ORDER BY Dialcode ASC LIMIT 1

多谢你们!

4

2 回答 2

2

我看到这里的主要问题是索引是建立在 Dialcode 的数值之上的——而不是字符串。所以这两个查询根本不使用索引。

您可以尝试构建一个数字函数,问题是该函数将在评估的左侧有 Dialcode - 因此不会再次使用索引。

也许这种方法可能更有用。

SELECT Dialcode 
FROM table 
WHERE ( (Dialcode BETWEEN %value% * 10 AND (%value%*10 + 9) 
   OR (Dialcode BETWEEN %value% * 100 AND (%value%*100 + 99) 
   OR (Dialcode BETWEEN %value% * 1000 AND (%value%*1000 + 999)
   ...
) AND Price IS NOT NULL
ORDER BY Dialcode LIMIT 1;

它丑得要命(我什至前两次都写错了——阿法辛应该因为纠正我而受到称赞),是的,但它应该会达到索引。另一种方法是使用 UNION(而不是 OR),但我想这两个查询将以相同的方式执行(虽然它没有经过验证)。

于 2012-06-18T22:45:15.180 回答
1

尝试使用正则表达式,例如:

SELECT Dialcode
FROM table
WHERE Dialcode REGEXP '^[$var]'
ORDER BY Dialcode ASC LIMIT 1

我现在无法测试它,但我相信它应该可以工作。

于 2012-06-18T23:00:32.710 回答