Можно ли отключить счетчик (всего) для ServiceStack AutoQuery?

Я настроил AutoQuery на простое объединение двух таблиц с приблизительно 1,3 миллионами строк. Используя встроенный мини-профилировщик для измерения времени SQL, запрос на возврат первых 100 строк (без фильтрации) занимает 3 мс, а счетчик - дополнительные 341 мс.

Можно ли использовать AutoQuery без получения счета? Мне на самом деле не нужно знать полный счет.

РЕДАКТИРОВАТЬ

Так что я подумал, что выяснить, осталось ли больше строк против полного счета, может быть быстрее. Я проверил это на нашей базе данных MSSQL с использованием SSMS для таймингов.

--Generated by ServiceStack
set statistics time on
SELECT COUNT(*) "COUNT(*)" 
FROM "table1" INNER JOIN "table2" ON
("table1"."PrimaryKey" = "table2"."ForeignKey")
set statistics time off

--Skipping 100
set statistics time on
SELECT CASE WHEN EXISTS(
  SELECT "table1"."PrimaryKey"
  FROM "table1" INNER JOIN "table2" ON
  ("table1"."PrimaryKey" = "table2"."ForeignKey")
  ORDER BY "table1"."PrimaryKey" OFFSET 100 ROWS FETCH NEXT 1 ROWS ONLY
) 
THEN CAST(1 AS BIT) 
ELSE CAST(0 AS BIT) END
set statistics time off

--Skipping 100000
set statistics time on
SELECT CASE WHEN EXISTS(
  SELECT "table1"."PrimaryKey"
  FROM "table1" INNER JOIN "table2" ON
  ("table1"."PrimaryKey" = "table2"."ForeignKey")
  ORDER BY "table1"."PrimaryKey" OFFSET 100000 ROWS FETCH NEXT 1 ROWS ONLY
) 
THEN CAST(1 AS BIT) 
ELSE CAST(0 AS BIT) END
set statistics time off

--Skipping 1000000
set statistics time on
SELECT CASE WHEN EXISTS(
  SELECT "table1"."PrimaryKey"
  FROM "table1" INNER JOIN "table2" ON
  ("table1"."PrimaryKey" = "table2"."ForeignKey")
  ORDER BY "table1"."PrimaryKey" OFFSET 1000000 ROWS FETCH NEXT 1 ROWS ONLY
) 
THEN CAST(1 AS BIT) 
ELSE CAST(0 AS BIT) END
set statistics time off

Выход:

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 203 ms,  elapsed time = 200 ms.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 16 ms,  elapsed time = 19 ms.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 203 ms,  elapsed time = 193 ms.

1 ответ

Решение

Дело не только в том, нужно ли вам знать полный счет или нет, но и Total также требуется для API ServiceClient, такого как GetLazy(), поэтому он может прозрачно передавать результаты AutoQuery за несколькими постраничными запросами.

Раньше это не было явным вариантом, но вы можете избежать запросов AutoQuery для Total, добавив ResponseFilter, который предварительно заполняет его одним, например:

Plugins.Add(new AutoQueryFeature {
    MaxLimit = 100,
    ResponseFilters = {
        ctx => { ctx.Response.Meta["COUNT(*)"] = "0"; }
    }
});

Я также только что добавил поддержку этой опции в этот коммит, поэтому в будущих выпусках вы можете удалить Total с помощью:

Plugins.Add(new AutoQueryFeature {
    MaxLimit = 100,
    IncludeTotal = false,
});

Это изменение доступно с версии 4.0.61, которая теперь доступна на MyGet.

Другие вопросы по тегам