1

実際のダイヤルコードよりも大きい最も近いダイヤルコードを検索する必要があります。たとえば、33から最も近いものは331または332になります(331が存在しない場合)...したがって、33xxxxである必要があり、34は無効です。

これらの2つのクエリは機能しますが、遅すぎます(250ms /行)。

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

私のダイヤルコードはPRIMARYKEYBIGINT(15)です。

私はこれを行っていますか、それは本当に速いです(> 1ms /行)が、それは私が必要としているものではありません:

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

だから私の問題はLIKE/MATCHAGAINSTだと思います。

任意のアイデアをいただければ幸いです。

更新ソリューション:

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;

それは地獄のように醜いです (私は最初の 2 回もこれを間違って書きました - alfasin は私を訂正した功績を認められるべきです)、はい、しかしそれはインデックスにヒットするはずです. 代替手段はUNIONを使用することです(ORではありません)が、両方のクエリが同じ方法で実行されると思います(ただし、検証されていません)。

于 2012-06-18T22:45:15.180 に答える