2014-09-12 2 views
1

Я использую jquery datatables для отображения сетки, которая использует webapi для извлечения данных. Webapi использует linq для запроса базы данных mssql, и он аккуратно использует фильтрацию, сортировку и пропустить/принять, чтобы собрать запрос на хорошо проиндексированную таблицу, содержащую около миллиона записей (и увеличиваясь). Общий сценарий.Получить SELECT COUNT асинхронно непрерывно

И он работает очень хорошо. Браузер должен подождать около 50 мс для ответа (например, для разбивки на страницы) для возврата.

Однако после того, как я посмотрел с помощью профилирующего инструмента, я заметил около 25 мс, который будет использоваться, просто выбирая общий вес таблицы. Который я хочу знать, потому что я хочу, чтобы datatable отображал что-то вроде: «отображение строки с 1 по 10 из 45.000, отфильтрованной из 1.000.000», которая нуждается в общем счете.

На самом деле мне не нужно знать точное общее количество (это просто информативное) каждую поездку с сервера, поэтому я, возможно, могу сохранить значение на стороне сервера и обновлять его каждую секунду в другой задаче, не мешая данным извлечение данных. Я бы просто вернул значение «достаточно близко» для общего количества строк.

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

Это, однако, нехорошо, но, используя статику и имеющую другое обновление нити, оно не кажется мне таким стабильным. Я посмотрел на SqlDependency, чтобы подталкивать показатель записи каждый раз, когда он изменяется от моих данных к моей модели домена, но, похоже, не поддерживает сценарии SELECT COUNT (Id) FROM TABLE.

Любые мысли?

+0

Что об использовании [MemoryCache] (http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache (V = vs.110) .aspx) запись с абсолютным истечением? –

+0

Конечно, лучше, чем статичный в веб-сценарии. Я согласен, но как обновить это стабильным образом. –

+0

Что вы подразумеваете под «стабильным»? Одним из вариантов обновления было бы добавить его с помощью 'CacheItemPolicy', который включает в себя' RemovedCallback', который заставит вызов снова получить счет. –

ответ

1

Если возможно, вы можете использовать одну из системных таблиц. Вы можете пингом каждую минуту и ​​вставлять его в кеш. Это article имеет два, что он претензии являются достаточными варианты:

--The way the SQL management studio counts rows (look at table properties, storage 
--, row count). Very fast, but still an approximate number of rows. 
SELECT CAST(p.rows AS float) 
FROM sys.tables AS tbl 
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2 
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) 
AND p.index_id=idx.index_id 
WHERE ((tbl.name=N'Transactions' 
AND SCHEMA_NAME(tbl.schema_id)='dbo')) 

или

--Quick (although not as fast as method 2) operation and equally important, reliable. 
SELECT SUM (row_count) 
FROM sys.dm_db_partition_stats 
WHERE object_id=OBJECT_ID('Transactions') 
AND (index_id=0 or index_id=1);  
+0

Это очень интересная статья. Я обязательно попробую. Однако недостаток заключается в том, что мне потребуется резкое отклонение от моей относительно чистой и простой первой модели кода для включения запроса в системную таблицу. Тем не менее, я собираюсь это рассмотреть. Благодарю. –

1

Рассматривали ли вы принимать подсчет при выполнении запроса, а затем вторя значение из ваших клиентов через SignalR?

В принципе, когда вызов LINQ возвращается, получите .Count() и передайте значение в фоновый поток, чтобы SignalR уведомлял клиентов об обновлении, в то же время вы возвращаете данные запрашивающему клиенту.

SignalR активирует функцию javascript на всех клиентских страницах, где вы можете взять переданное значение и отобразить его где-нибудь на странице.

http://www.asp.net/signalr

+0

Я не считал это на самом деле. Это интересный подход, и он может работать, поскольку все пользователи веб-приложения просматривают одну и ту же таблицу с одинаковым общим количеством записей. Я мог бы комбинировать это, имея первое значение при загрузке страницы, просто вставьте его в бритву. После этого я обновляю его с помощью signalr. Интересно. Спасибо. Я дам вам знать, если я попробую. –

+0

Я использую эту технику прямо сейчас, чтобы фактически заполнять данные таблицы в некоторых сценариях для моих пользователей. Когда данные обновляются, я беру один запрос из него, а затем передаю весь результат клиенту. 1 попадает в БД, и каждый получает обновление. – TechneWare

+0

Звучит аккуратно, я мог использовать его только для общего счета. Пользователи имеют сложные фильтры на стороне клиента в своих браузерах. Пока они смотрят на один стол, они, разумеется, не смотрят на тот же набор результатов. На самом деле, я не сделал ничего полезного с signalr, так что это может быть интересно посмотреть. Мне по-прежнему нужен серверный таймер, чтобы получить последнюю итоговую сумму. И использование цикла с резьбой в MVC кажется уродливым. –