SQL通配符搜索 - 效率?

Jer*_*026 14 sql sql-server query-optimization processing-efficiency sql-server-2008

最近在使用LIKE和通配符搜索MS SQL数据库的最有效方法上进行了辩论.我们使用的比较%abc%,%abcabc%.有人说你应该在学期末(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')
Run Code Online (Sandbox Code Playgroud)

CLMASTER拥有大约500,000条记录,大约有7,400个地址以"Street"结尾,大约8,500个地址包含"Street",但不一定在最后.每次测试运行花了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>";

?>
Run Code Online (Sandbox Code Playgroud)

此测试的结果与在SQL Server中测试时的结果一样模糊.

%STREET 完成时间为166.5823秒(每个查询平均值为.3331),平均值为.0228,结果为500.

%STREET%在149.4500秒内完成(每个查询平均为.2989),在.0177中找到平均500个结果.(每个结果的更快时间,因为它在相似的时间内找到比其他结果更多的结果.)

reverse(ADDRESS) like reverse('%STREET') 完成时间为134.0115秒(每次查询平均值为.2680),平均结果为500秒,结果为.0183秒.

reverse('TREETS%') 完成时间为167.6960秒(每个查询平均值为.3354),平均值为.0229,结果为500.

我们预计此测试将显示%STREET%整体速度最慢,而实际上运行速度最快,并且平均时间最长可返回500个结果.虽然建议reverse('%STREET')整体运行速度最快,但返回500结果的速度要慢一些.

额外的乐趣:当我们运行测试时,同事在服务器上运行分析器,发现使用双通配符会显着增加CPU使用率,而其他测试则相互之间的1-2%.

是否有任何SQL效率专家可以解释为什么在搜索字符串末尾使用通配符比开头更好的做法,也许为什么在字符串的开头和结尾使用通配符进行搜索比使用通配符更快刚刚开始?

Bor*_*ort 20

如果该列被索引,那么在字符串末尾加上通配符'abc%'会有所帮助,因为它可以直接查找以其开头的记录并忽略其他所有内容.在开头使用外卡意味着它必须查看每一行,无论索引如何.'abc'

好文章在这里有更多解释.

  • 从某种程度上说,这意味着做像'abc%'这样的'反向(col)'这样的事情是个坏主意. (2认同)