Для тех, кто заявляет, что Any () - это путь вперед, я провел простой тест в LinqPad с базой данных SQL CommonPasswords, 14 миллионов «давай или бери».
Код:
var password = "qwertyuiop123";
var startTime = DateTime.Now;
"From DB:".Dump();
startTime = DateTime.Now;
if (CommonPasswords.Any(c => System.Data.Linq.SqlClient.SqlMethods.Like(c.Word, password)))
{
$"FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
else
{
$"NOT FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
"From DB:".Dump();
startTime = DateTime.Now;
if (CommonPasswords.Where(c => System.Data.Linq.SqlClient.SqlMethods.Like(c.Word, password)).Count() > 0)
{
$"FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
else
{
$"NOT FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
"From DB:".Dump();
startTime = DateTime.Now;
if (CommonPasswords.Where(c => c.Word.ToLower() == password).Take(1).Any())
{
$"FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
else
{
$"NOT FOUND: processing time: {(DateTime.Now - startTime).TotalMilliseconds}\r\n".Dump();
}
Вот перевод SQL:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'qwertyuiop123'
-- EndRegion
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [Security].[CommonPasswords] AS [t0]
WHERE [t0].[Word] LIKE @p0
) THEN 1
ELSE 0
END) AS [value]
GO
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'qwertyuiop123'
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [Security].[CommonPasswords] AS [t0]
WHERE [t0].[Word] LIKE @p0
GO
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'qwertyuiop123'
-- EndRegion
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT TOP (1) NULL AS [EMPTY]
FROM [Security].[CommonPasswords] AS [t0]
WHERE LOWER([t0].[Word]) = @p0
) AS [t1]
) THEN 1
ELSE 0
END) AS [value]
Вы можете видеть, что ЛЮБОЙ упаковывает запрос в другой слой кода, чтобы выполнить CASE, где существует, тогда 1, где Count () просто добавляет команду Count. Проблема с обоими из них в том, что вы не можете сделать Top (1), но я не вижу лучшего способа, используя Top (1)
Результаты:
из БД:
НАЙДЕНО: время обработки: 13.3962
из БД:
НАЙДЕНО: время обработки: 12.0933
из БД:
НАЙДЕНО: время обработки: 787.8801
Еще раз:
из БД:
НАЙДЕНО: время обработки: 13.3878
из БД:
НАЙДЕНО: время обработки: 12.6881
из БД:
НАЙДЕНО: время обработки: 780.2686
Еще раз:
из БД:
НАЙДЕНО: время обработки: 24.7081
из БД:
НАЙДЕНО: время обработки: 23.6654
из БД:
НАЙДЕНО: время обработки: 699.622
без индекса:
из БД:
НАЙДЕНО: время обработки: 2395.1988
из БД:
НАЙДЕНО: время обработки: 390.6334
из БД:
НАЙДЕНО: время обработки: 664.8581
Теперь некоторые из вас могут думать, что это всего лишь миллисекунда или две. Однако различие было намного больше, прежде чем я поместил в него индекс; на несколько секунд.
Последнее вычисление началось с того, что я начал с представления о том, что ToLower () будет быстрее, чем LIKE, и я был прав, пока не попробовал считать и не поместил в него индекс. Я полагаю, что Lower () делает индекс бесполезным.