繁体   English   中英

字符串太长时无法执行查询

[英]Cannot execute query when the string is too long

我正在尝试运行通常可以正常运行的查询,但是如果列表太大,则会收到超时错误。

这是我的代码:

public async Task<IEnumerable<User>> GetUsers(IEnumerable<int> ids)
{
    if (ids.IsNullOrEmpty())
    {
        return Enumerable.Empty<User>();
    }

    string query = $@"  SELECT  *
                        FROM    dbo.Users
                        WHERE   Id IN ({string.Join(",", ids)})";

    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        return await conn.QueryAsync<TEntity>(query);
    }
}

如果id数量很少(少于100K),则可以正常工作。 但是,如果计数约为1百万,则会导致SQL超时异常。

当我查看SQL事件探查器时,我发现查询甚至没有运行。

我究竟做错了什么? 在C#=> SQL Server查询中处理海量数据的一种好解决方案或好方法是什么?

提前致谢。

我在这里看到多个问题,然后尝试在这里退后一步:

首先,就像其他人提到的那样,传递参数的方式不是最理想的。 IN不能传递这么长的参数列表。 在这种情况下,IN使用大量资源,很可能导致您发现问题。

为此的技术解决方案是创建一个临时表或使用并加入用户表。 正如评论中指出的那样,这不是同一件事,并且FROM(VALUES())在某些情况下可以工作,但在其他情况下则不能。

有了临时表,它看起来像

    string query = $@"  CREATE TABLE @ids (id INT);

                        INSERT INTO @ids VALUES {string.Join(",", ids.Select(id => $"({id})"))}

                        SELECT  u.*
                        FROM    @ids Ids
                        JOIN    dbo.Users u ON u.Id = Ids.Id

也有可能使用FROM (VALUES(...)) ,但是正如下面我的评论者所提到的,这不保证有效。 它看起来像这样:

    string query = $@"  SELECT  u.*
                        FROM    (
                                    VALUES {string.Join(",", ids.Select(id => $"({id})"))} 
                                ) AS Ids(Id)
                        JOIN    dbo.Users u ON u.Id = Ids.Id";

我注意到的第二件事是,此查询始终加载完整的用户对象。 我假设调用方法会对那些仅是用户数据子集的用户进行某些操作? 在这种情况下,只返回应用程序特定步骤中所需的数据并进行有限的选择会更干净。 这减少了需要从磁盘读取并大量传输到应用程序的数据量,因此可以极大地提高性能。

一种方法是将您的ids集合划分为若干位,比如说100K(因为它可以处理该数量的ID)并多次查询数据库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM