SQL Wildcard Search - Efficacité?

Il y a eu un débat au travail récemment à la manière la plus efficace pour rechercher une base de données MS SQL à l'aide de LIKE et des caractères génériques. Nous le comparons à l'aide de %abc%%abcet abc%. Une personne a dit que vous devriez toujours avoir le générique à la fin de la période (abc%). Donc, selon eux, si nous voulions trouver quelque chose qui s'est terminée en "abc", il serait plus efficace d'utiliser la fonction "inverse(colonne) inverse (en% "abc").

- Je configurer un test à l'aide de SQL Server 2008 (R2) pour comparer chacun des énoncés suivants:

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 détient environ 500 000 enregistrements, il y a quelque 7 400 adresses de fin "de la Rue", et environ 8 500 adresses "de la Rue", mais pas nécessairement à la fin. Chaque essai a pris 2 secondes, et ils ont tous retourné le même nombre de lignes à l'exception de %STREET%qui a trouvé un supplément de 900 ou alors des résultats car il a ramassé les adresses qui ont un numéro d'appartement sur la fin.

Depuis le Serveur SQL server test n'a montré aucune différence dans le temps d'exécution, j'ai déménagé en PHP où j'ai utilisé le code suivant, la commutation dans chaque état, pour exécuter plusieurs tests rapidement:

<?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>";

?>

Les résultats de ce test était à peu près aussi ambigu que les résultats lors de l'essai de SQL Server.

%STREET achevé en 166.5823 secondes (.3331 moyenne par requête), et en moyenne 500 résultats présents dans .0228.

%STREET% achevé en 149.4500 secondes (.2989 moyenne par requête), et en moyenne 500 résultats présents dans .0177. (Plus rapide temps par la suite parce qu'il trouve plus de résultats que les autres, en même temps.)

reverse(ADDRESS) like reverse('%STREET') achevé en 134.0115 secondes (.2680 moyenne par requête), et en moyenne 500 résultats trouvés dans .0183 secondes.

reverse('TREETS%') achevé en 167.6960 secondes (.3354 moyenne par requête), et en moyenne 500 résultats présents dans .0229.

Nous nous attendions à ce que ce test montrent que %STREET% serait le plus lent dans l'ensemble, alors que c'était en fait le plus rapide à exécuter, et qui a la meilleure moyenne de temps de retour de 500 résultats. Alors que le suggère reverse('%STREET') a été le plus rapide à exécuter dans l'ensemble, mais un peu plus lentement dans le temps pour revenir 500 résultats.

Plus de plaisir: Un collègue a couru profiler sur le serveur alors que nous étions à en exécuter les tests et constaté que l'utilisation de la double joker a produit une augmentation significative de l'utilisation de l'UC, tandis que les autres tests ont été dans un délai de 1-2% de l'autre.

Y a-SQL experts de l'Efficacité que peut expliquer pourquoi le générique à la fin de la chaîne de recherche serait préférable que le début, et peut-être pourquoi la recherche avec des caractères génériques au début et à la fin de la chaîne a été plus rapide que d'avoir le générique juste au début?

source d'informationauteur Jeremy1026 | 2012-08-03