【问题标题】:How to speed up querying same table many times with different conditions?如何加快不同条件下多次查询同一张表的速度?
【发布时间】:2019-11-09 01:32:50
【问题描述】:

后台使用EF6、asp mvc core和SQL Server。

我必须以不同的条件对同一张表进行多次查询,f.e.

SELECT COUNT(*) FROM Table1 WHERE a = true
SELECT COUNT(*) FROM Table1 WHERE b = true
SELECT COUNT(*) FROM Table1 WHERE a = true || b = true
SELECT a FROM Table1 WHERE b = true

所以对Table1 进行了 4 次不同条件的查询。我认为因此我必须阅读整个Table1 四次。在伪代码中它可能看起来像这样。

var res1 = new list();

foreach(var rec in Table1) 
{
    // read Table1 first time
    if(rec.a == true) 
    {
        res1.push(rec);
    }
}

var res2 = new list();

foreach(var rec in Table1) 
{
    // read Table1 second time
    if(rec.b == true) 
    {
        res2.push(rec);
    }
}

var res3 = new list();

foreach(var rec in Table1) 
{
     // read Table1 third time
     if(rec.a == true || rec.b == true) 
     {
         res3.push(rec);
     }
}

var res4 = new list();

foreach(var rec in Table1) 
{ 
    // read Table1 fourth time
    if(rec.b == true) 
    {
        res4.push(rec);
    }
}

我想知道如何只读取一次Table1 并获得四种不同的结果,如下所示:

var res1 = new List();
var res2 = new List();
var res3 = new List();
var res4 = new list();

foreach(rec in Table1) 
{
     // read Table1 first time
     if(a == true) 
     {
        res1.push(rec);
     } 

     if(b == true) 
     {
        res2.push(rec);
     }

     if(a == true || b == true) 
     {
        res3.push(rec);
     }

     if(b == true) 
     {
        res4.push(rec);
     }  
}  

还有一个挑战,这些查询是动态 sql,我的意思是 a = trueb = truea = true || b = true 存储在数据库中。查询是以这种方式运行的:

string query = "SELECT Count(*) FROM Table1 WHERE" + condition;
var count = ExecuteSql(query);

上面的示例被简化了,但实际上所有的查询都被拆分并存储在数据库中。

PS。实际上我想加快页面速度,向服务器发出 30-40 个请求,每个请求都是对同一张表的查询。我想如果我可以用一个请求而不是 40 个请求来替换它们。

【问题讨论】:

    标签: sql sql-server entity-framework optimization


    【解决方案1】:

    您可以只使用一个查询来使用条件聚合:

    SELECT
        COUNT(CASE WHEN a = true THEN 1 END) AS cnt_a,
        COUNT(CASE WHEN b = true THEN 1 END) AS cnt_b,
        COUNT(CASE WHEN a = true OR b = true THEN 1 END) AS cnt_a_b
    FROM Table1;
    

    这会将全表扫描的次数从 3 次减少到仅 1 次。此外,它还可能将往返数据库的次数从 3 次减少到 1 次。

    【讨论】:

    • 看起来很有希望,我会试试的。
    猜你喜欢
    • 2016-09-25
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2019-02-21
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    相关资源
    最近更新 更多