.net 对于许多值,SQL Server IN子句的速度更快
我正在使用OrmLite.NET和SQL Server 12.0。我想选择一个实体,其中某个整数列(不是主键)具有数组中的多个值之一。类似这样的OrmLite表达式:.net 对于许多值,SQL Server IN子句的速度更快,.net,sql-server,ormlite-servicestack,.net,Sql Server,ormlite Servicestack,我正在使用OrmLite.NET和SQL Server 12.0。我想选择一个实体,其中某个整数列(不是主键)具有数组中的多个值之一。类似这样的OrmLite表达式: q => query.Where(r => myIntegers.Contains(r.TheColumn)) 被翻译成 WHERE "TheColumn" IN (1, 2, 3, ...) -- my integers 这在~100时工作正常,但在1000时超时。如何使用较大的列表实现相同的效果?我可以以某种方
q => query.Where(r => myIntegers.Contains(r.TheColumn))
被翻译成
WHERE "TheColumn" IN (1, 2, 3, ...) -- my integers
这在~100时工作正常,但在1000时超时。如何使用较大的列表实现相同的效果?我可以以某种方式将数组或表参数传递给SQL Server吗?与@JoeTaras所评论的类似,您可以将可接受的值放入子查询中,类似于
SELECT TheColumn from TheTable T
INNER JOIN (SELECT * from (VALUES(1),(2),(3),(4)) as V1(value)) V
ON T.TheColumn = V.value
在OrmLite中,您可以构建所需的原始SQL查询,例如,从@Sam cd answer,并将其传递给db。选择方法:
我最终为此使用了一个临时表,即:
CREATE TABLE #ParamTempTable (Id BIGINT NOT NULL PRIMARY KEY);
INSERT INTO #ParamTempTable (Id) VALUES ((1), (2), (3));
SELECT *
FROM MyTable
WHERE Id IN (SELECT * FROM #ParamTempTable);
DROP TABLE #ParamTempTable;
我只在值大于1000时才这样做,否则我只在1、2、3中使用SQL
为了在OrmLite上实现这一点,我必须对SqlServerExpression进行子类化,并重写VisitStaticarayMethodCall和VisitEnumerableMethodCall,以更改它处理包含表达式的方式。这个类分别存储创建和删除临时表的命令,我必须为每个临时表分别运行一个SqlCommand。很遗憾,CREATE TABLE在SqlCommand.ExecuteReader中不起作用。因此,这非常复杂,但它确实有效,并且对调用方是透明的。另一个好处是,我可以消除重复的参数,例如,对于o=>ids.Containso.FromId | | | ids.Containso.ToId,列表ID只发送到SQL server一次。在子查询中转换数组,或者通过创建临时表与querySQL server的其他表连接,都支持表值参数。。但我对奥姆莱特一无所知。我对奥姆莱特一无所知,所以请恕我直言。要使其工作,答案中的sql不需要位于数据库的视图中,然后映射到某个实体吗?那么您会在OP的linq查询中包含该实体吗?
CREATE TABLE #ParamTempTable (Id BIGINT NOT NULL PRIMARY KEY);
INSERT INTO #ParamTempTable (Id) VALUES ((1), (2), (3));
SELECT *
FROM MyTable
WHERE Id IN (SELECT * FROM #ParamTempTable);
DROP TABLE #ParamTempTable;