我的网络应用程序中启用了一个基本网格,并启用了分页。使用Dapper通过Web API使用SQL数据填充此网格。在我的API控制器中,我运行两个单独的查询:一个用于提取行(显示在我的网格中),另一个用于获取记录总数(在我的分页控件中显示)。这很有效。但是,我正在尝试优化我的查询。
我的第一个提取行的查询一次只返回50行(使用OFFSET
和FETCH
,以提供分页:
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
子句在两者之间是相同的。
您可以尝试此查询:
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
您可以根据确定结果集中的不同记录的内容来简化上述查询。
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.5
秒执行的,这对于只有简单连接的查询看起来很奇怪,而且只需要获取50 records
或count all
。我知道这取决于表的大小和服务器的硬件,但仍然如此。
所以我认为你可以优化它们,并且不需要将它们“合并”成一个。
我先看一下查询执行计划。我很确定它可以大大加快。所以,请将查询计划添加到您的问题中。
但即使没有疑问,我也有一些问题:
distinct
?T_INDEX.CallTime
的索引吗?