我可以在单个查询中检索分页行数和总计数吗?

时间:2017-12-22 03:26:46

标签: sql sql-server

我的网络应用中启用了分页的基本网格。使用Dapper通过Web API使用SQL数据填充此网格。在我的API控制器中,我运行两个单独的查询:一个用于提取行(显示在我的网格中),另一个用于获取记录总数(在我的分页控件中显示)。这很有效。但是,我正在尝试优化我的查询。

我的第一个提取行的查询一次只返回50行(使用OFFSETFETCH,以提供分页:

SELECT DISTINCT T_INDEX.* 
FROM T_INDEX
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId
WHERE... --a fairly complex WHERE statement
ORDER BY CallTime DESC
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY

我的第二个查询提取所有行的计数,但使用相同的表,相同的连接和相同的WHERE子句:

SELECT COUNT(DISTINCT T_INDEX.IndexId)
FROM T_INDEX
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId
WHERE... --the same fairly complex WHERE statement

正如我所说,这是有效的。每次查询大约需要2.5秒,总共5秒以上。无论如何,时间滞后不是世界末日,但我希望将时间缩短一半。

我想知道是否有任何方法可以检索50行检索一个查询中所有行的总数。我意识到这两个查询正在做两件事。但我的想法是,有可能"是一种调整这两个查询并将它们合并为一个的方法,因为表,连接和WHERE子句在两者之间是相同的。

3 个答案:

答案 0 :(得分:1)

您可以尝试使用此查询:

SELECT *
FROM (
   SELECT *, COUNT(*) OVER () AS cnt
   FROM (
      SELECT DISTINCT T_INDEX.*, 
      FROM T_INDEX
      INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId
      WHERE... --a fairly complex WHERE statement
   ) AS t1 ) AS t2
ORDER BY CallTime DESC
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY

您可以根据确定结果集中不同记录的内容来简化上述查询。

答案 1 :(得分:0)

SELECT DISTINCT T_INDEX.*,
        (SELECT COUNT(DISTINCT T_INDEX.IndexId)  FROM T_INDEX
           INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = 
           T_INDEXCALLER.IndexIdAS) AS  TotalCount
FROM T_INDEX
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId
WHERE... --a fairly complex WHERE statement
ORDER BY CallTime DESC
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY

答案 2 :(得分:0)

我提出了另一个解决方案:不要进行盲目优化

你只是想变得幸运 - 这是不合理的。

他们没有做同样的事情,因此他们可能会单独进行优化。但更重要的是,您的两个查询都执行了2.5秒,这些查询对于只有简单连接的查询而言看起来很奇怪,并且只需获取50 recordscount all。我知道这取决于表格和服务器硬件的大小,但仍然。

所以我认为你可以优化它们,并且不需要"合并"他们合二为一。

我先查看查询执行计划。我很确定它可以大大加快。所以,请将查询计划添加到您的问题中。

但即使没有疑问,我也有一些问题:

  • 为什么distinct
  • 您有T_INDEX.CallTime的索引吗?