我需要搜索比实际更大的Dialcode。例如,最接近33的将是331或332(如果331不存在)......所以它必须是33xxxx,34是无效的。
这两个查询有效但速度太慢(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
我的拨号码是一个主要的大键(15)。
我这样做,它真的很快(> 1毫秒/行),但这不是我需要的:
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
谢谢你们!
答案 0 :(得分: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;
这很丑陋(我甚至在前两次写错了 - alfasin应该得到纠正我的功劳),是的,但它应该达到指数。另一种方法是使用UNION(而不是OR),但我认为两个查询都将以相同的方式执行(但它没有经过验证)。
答案 1 :(得分:1)
尝试使用正则表达式,例如:
SELECT Dialcode
FROM table
WHERE Dialcode REGEXP '^[$var]'
ORDER BY Dialcode ASC LIMIT 1
我现在无法测试它,但我相信它应该可行。