慢 mysql 查询与喜欢/匹配



我需要搜索比实际更大的最接近的拨号代码。例如,与 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

我现在无法测试它,但我相信它应该有效。

最新更新