我需要搜索比实际更大的最接近的拨号代码。例如,与 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
我的拨号码是一个主键 BIINTINT(15)。
我这样做,它真的很快(>1ms/行),但它并不是我所需要的:
SELECT Dialcode
FROM table
WHERE (Dialcode >= '$var' AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1
所以我想我的问题是喜欢/匹配。
任何想法将不胜感激。
更新解决方案:
解决方案改编自 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
谢谢大家!
我看到这里的主要问题是索引建立在拨号码的数值上 - 而不是字符串值。因此,这两个查询根本不使用索引。
您可以尝试构建一个数字函数,问题是该函数在评估的左侧会有 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),但我想这两个查询将以相同的方式执行(尽管尚未验证)。
尝试使用正则表达式,如下所示:
SELECT Dialcode
FROM table
WHERE Dialcode REGEXP '^[$var]'
ORDER BY Dialcode ASC LIMIT 1
我现在无法测试它,但我相信它应该有效。