Ограничить количество строк, возвращаемых на стороне сервера (принудительное ограничение) - PullRequest
6 голосов
/ 20 мая 2010

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

У меня нет реальной надежды на то, что найдется решение, я осмотрелся и не вижу никаких способов сделать это, однако я надеюсь, что у кого-то может быть идея.

Заранее спасибо.

EDIT

Я забыл важную часть информации, у нас нет доступа к исходному коду, поэтому мы не можем изменить это на стороне клиента, где формируется оператор SQL. Реального компонента на стороне сервера нет, клиент просто обращается к базе данных напрямую. Любое решение в основном требует процедуры, триггера или какого-либо параметра / команды SQL-Server 2008.

Ответы [ 5 ]

2 голосов
/ 20 мая 2010

Одним из возможных решений может быть

  • переименуйте оскорбительную таблицу
  • создать обновляемое представление с исходным именем таблицы
  • сделать SELECT TOP x * FROM OffendingTable как определение вашего представления

Таким образом, клиент не знает об изменении при выборе данных.


Используйте регулятор запросов

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

1 голос
/ 20 мая 2010

Если клиент использует TCP для подключения к базе данных, вы можете вставить в основном прозрачный прокси-сервер TCP между клиентом и сервером базы данных на стороне сервера. Затем вы можете переписать любые оскорбительные запросы, поступающие от клиента (используя TOP или некоторые способы улучшения запроса).

Затем вы настраиваете SQL Server для запуска на другом порту, запускаете прокси-сервер для обслуживания на исходном порту и подключаете его к SQL-серверу на новом порту. Если вы знаете исходный IP-адрес клиента, вы можете использовать переадресацию портов, чтобы перенаправить только их на прокси-сервер и оставить сервер базы данных настроенным как есть.

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

1 голос
/ 20 мая 2010

Вы можете использовать выберите верх

ВЫБЕРИТЕ ТОП 50 ПРОЦЕНТОВ * ОТ ЛИЦ (http://www.w3schools.com/sql/sql_top.asp)

)

или

Поможет ли вам пейджинг, подобный этому

CREATE PROCEDURE [dbo].[GetRequestedRecordByPage] 
 @FromList nvarchar(200)              -- Table Name  
,@SortingCol nvarchar(200)         -- Sorting column Name
,@SelectList nvarchar(200) = '*'         -- Select columns list
,@WhereClause nvarchar(200) = ''        -- Where clause i.e condition
,@PageNum int = 1                           -- Requested page number
,@PageSize int = 5                 -- No of record in page
,@TotalNoOfRecord int output         -- Total no of selected records
AS 
Begin
  SET NOCOUNT ON 
  DECLARE @Query nvarchar(max)         -- query going to be execute

  IF rtrim(ltrim(@WhereClause)) <> '' 
  BEGIN
      SET @Query ='SELECT   @TotalNoOfRecord = COUNT(*) 
                      FROM     ' + @FromList + ' 
        WHERE    ' + @WhereClause 
  END
  ELSE 
  BEGIN 
      SET @Query ='SELECT   @TotalNoOfRecord = COUNT(*) 
                      FROM     ' + @FromList 
  END

    /* Count no. of record */
       EXEC sp_executeSQL 
        @Query, 
        @params = N'@TotalNoOfRecord INT OUTPUT', 
         = @TotalNoOfRecord OUTPUT 

DECLARE @lbound int, @ubound int 




/* Calculating upper and lower bound */
        SET @lbound = ((@PageNum - 1) * @PageSize) 
        SET @ubound = @lbound + @PageSize + 1 


/* Get list of record(s) */
        SELECT @Query =  ''
        SELECT @Query =  'SELECT  * 
                          FROM    ( 
SELECT  ROW_NUMBER() OVER(ORDER BY ' + @SortingCol  + ') AS rownumber,' +@SelectList  +   
                                        ' FROM    ' + @FromList 

        IF rtrim(ltrim(@WhereClause)) <> '' 
        BEGIN
            SELECT @Query = @Query + ' WHERE   ' + @WhereClause 
        END

            SELECT @Query = @Query + '     ) AS tbl 
WHERE rownumber > ' + CONVERT(varchar(9), @lbound) + 
      ' AND rownumber < ' + CONVERT(varchar(9), @ubound) 

       EXEC (@Query)                 
End
1 голос
/ 20 мая 2010

Для этого должна быть команда.

Я знаю, что в MYSQL это «LIMIT (firstindex, lastindex)» в конце оператора SQL.

Я думаю, что я слышал в MSSQL вы можете написать:

Выберите ТОП 10,20 ... или что-то в этом роде

Это означало бы, что вы выбрали 20 строк с 10 начала, я думаю,

0 голосов
/ 20 мая 2010

Вы можете удалить все записи, кроме X, из таблицы и сохранить их где-нибудь еще

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...