Para aquellas personas que afirman que Any() es el camino a seguir, hice una prueba simple en LinqPad contra una base de datos SQL de CommonPasswords, 14 millones de dar o recibir. Código:
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();
}
Aquí está el SQL traducida:
-- 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]
Se puede ver que cualquier envuelve la consulta en otra capa de código para hacer un caso en el que existe, entonces 1 donde como Count() solo agrega un comando de Cuenta. El problema con estos dos es que no puede hacer una parte superior (1), pero no puede ver una mejor manera el uso de Arriba (1)
Resultados:
De DB: encontrado: el tiempo de procesamiento: 13.3962
De DB: Encontrado: tiempo de procesamiento: 12.0933
De DB: Encontrado: tiempo de procesamiento: 787,8801
Una vez más:
De DB: Encontrado: Tiempo de procesamiento: 13.3878
De DB: Encontrado: Tiempo de procesamiento: 12.6881
De DB: Encontrado: Tiempo de procesamiento: 780,2686
Una vez más:
De base de datos: ENCONTRADO: tiempo de procesamiento: 24.7081
De base: encontrado: el tiempo de procesamiento: 23.6654
De DB: encontrado: el tiempo de procesamiento: 699.622
sin índice:
De DB: encontrado: Tiempo de ejecución: 2.395.1988
De DB: encontrado: el tiempo de procesamiento: 390,6334
De DB: encontrado: el tiempo de procesamiento: 664,8581
Ahora algunos de ustedes pueden estar pensando que es sólo una milésima de segundo o dos. Sin embargo, la variedad era mucho mayor antes de poner un índice sobre ella; por unos segundos.
El último cálculo está allí ya que comencé con la noción de que ToLower() sería más rápido que LIKE, y tenía razón, hasta que intenté contar y poner un índice en él. Supongo que Lower() hace que el índice sea relajante.
Combinatum extra solo porque nunca me di cuenta de que había una característica de registro de SQL para Sql. He tenido que ejecutar SQL Profiler todo este tiempo. – David
@David - de hecho. Sigo pidiéndole al equipo de datos de MS que lo agregue a EF ;-p –
¿y si quiere ** utilizar a los Usuarios después ** en lugar de escribir una segunda consulta en la base de datos? compruebe [esto] (http://stackoverflow.com/a/1071063/2218697), la esperanza ayuda a alguien. – stom