LIKE
最近、ワイルドカードを使用してMSSQLデータベースを検索する最も効率的な方法について議論が行われています。%abc%
、、、%abc
を使用して比較していabc%
ます。ある人は、用語の終わりには常にワイルドカードを使用する必要があると言っています(abc%
)。したがって、彼らによると、「abc」で終わるものを見つけたい場合は、 `reverse(column)LIKE reverse('%abc')を使用するのが最も効率的です。
SQL Server 2008(R2)を使用してテストを設定し、次の各ステートメントを比較しました。
select * from CLMASTER where ADDRESS like '%STREET'
select * from CLMASTER where ADDRESS like '%STREET%'
select * from CLMASTER where ADDRESS like reverse('TEERTS%')
select * from CLMASTER where reverse(ADDRESS) like reverse('%STREET')
CLMASTERは約500,000レコードを保持し、「Street」で終わる約7,400のアドレスと、「Street」が含まれるが必ずしも最後ではない約8,500のアドレスがあります。各テストの実行には2秒かかり%STREET%
、最後にアパート番号が付いている住所を取得したため、900程度の追加の結果が見つかった以外は、すべて同じ量の行が返されました。
SQL Serverテストでは実行時間に違いが見られなかったため、PHPに移行し、次のコードを使用して各ステートメントを切り替え、複数のテストをすばやく実行しました。
<?php
require_once("config.php");
$connection = odbc_connect( $connection_string, $U, $P );
for ($i = 0; $i < 500; $i++) {
$m_time = explode(" ",microtime());
$m_time = $m_time[0] + $m_time[1];
$starttime = $m_time;
$Message=odbc_exec($connection,"select * from CLMASTER where ADDRESS like '%STREET%'");
$Message=odbc_result($Message,1);
$m_time = explode(" ",microtime());
$m_time = $m_time[0] + $m_time[1];
$endtime = $m_time;
$totaltime[] = ($endtime - $starttime);
}
odbc_close($connection);
echo "<b>Test took and average of:</b> ".round(array_sum($totaltime)/count($totaltime),8)." seconds per run.<br>";
echo "<b>Test took a total of:</b> ".round(array_sum($totaltime),8)." seconds to run.<br>";
?>
このテストの結果は、SQLServerでテストしたときの結果とほぼ同じくらいあいまいでした。
%STREET
166.5823秒(クエリあたり平均.3331)で完了し、.0228で平均500件の結果が見つかりました。
%STREET%
149.4500秒(クエリあたり平均.2989)で完了し、.0177で平均500件の結果が見つかりました。(同様の時間に他の結果よりも多くの結果が見つかるため、結果ごとの時間が短縮されます。)
reverse(ADDRESS) like reverse('%STREET')
134.0115秒(クエリあたり平均.2680)で完了し、.0183秒で平均500件の結果が見つかりました。
reverse('TREETS%')
167.6960秒(クエリあたり平均.3354)で完了し、.0229で平均500件の結果が見つかりました。
このテストで%STREET%
は、全体的に最も遅いことが示されると予想しましたが、実際には実行が最も速く、500件の結果を返すのに最適な平均時間がありました。提案さreverse('%STREET')
れたものは全体的に実行するのが最も速かったが、500の結果を返すのに少し時間がかかった。
さらに楽しい:テストの実行中に同僚がサーバーでプロファイラーを実行したところ、ダブルワイルドカードを使用するとCPU使用率が大幅に増加し、他のテストは互いに1〜2%以内であることがわかりました。
検索文字列の最後にワイルドカードを付ける方が最初よりも優れている理由、および文字列の最初と最後にワイルドカードを使用する方がワイルドカードを使用するよりも高速である理由を説明できるSQL効率の専門家はいますか?初めに?