我的网络应用中启用了分页的基本网格。使用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
子句在两者之间是相同的。
答案 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 records
或count all
。我知道这取决于表格和服务器硬件的大小,但仍然。
所以我认为你可以优化它们,并且不需要"合并"他们合二为一。
我先查看查询执行计划。我很确定它可以大大加快。所以,请将查询计划添加到您的问题中。
但即使没有疑问,我也有一些问题:
distinct
?T_INDEX.CallTime
的索引吗?