2010-05-20 25 views
6

Tenemos un programa que tiene una declaración SQL mal escrita que causa que se devuelva cada fila de una tabla. Hay varios millones de filas en la tabla, por lo que esto está causando problemas graves de memoria y bloqueos en la máquina de nuestros clientes. El proveedor está en el proceso de crear un parche para el problema, sin embargo, todavía quedan algunas semanas. Mientras tanto, intentábamos encontrar un método para limitar el número de resultados devueltos en el lado del servidor solo como solución temporal.Limite el número de filas devueltas en el lado del servidor (límite forzado)

No tengo ninguna esperanza real de que haya una solución, he mirado alrededor y realmente no veo ninguna forma de hacerlo, sin embargo, espero que alguien pueda tener una idea.

Gracias de antemano.

EDITAR

me olvidó una pieza importante de información, no tenemos acceso al código fuente por lo que no puede cambiar esto en el lado del cliente, donde se forma la instrucción SQL. No existe un componente real del lado del servidor, el cliente simplemente accede directamente a la base de datos. Cualquier solución requeriría básicamente un procedimiento, desencadenador o algún tipo de configuración/comando SQL-Server 2008.

+0

¿No solucionará esa aplicación temporal la aplicación? ¿Sabes cómo se utilizan estos datos? – Paddy

+2

Cambie el nombre de la tabla y reemplácela con una vista que tenga un 'SELECT TOP x * FROM new_name_of_the_table'. Sin embargo, tenga en cuenta que las manipulaciones de datos (INSERT, UPDATE, DELETE) realizadas por la aplicación fallarán posteriormente. – Heinzi

+0

@Heinzi Desafortunadamente tendríamos que poder insertar, actualizar y eliminar. – tplaner

Respuesta

2

Una posible solución podría ser la de

  • cambiar el nombre de la tabla infractor
  • crear una updatable view con el nombre de tabla original,
  • hacer un SELECT TOP x * FROM OffendingTable como su definición de vista

Como tal, el cliente no tiene conocimiento del cambio al seleccionar los datos.


Utilice la query governor

Si no le importa devolver ningún dato en absoluto para la consulta ofensor, el regulador de consultas permite que lo haga.

+0

Excelente sugerencia, similar al comentario de Heinzi, sin embargo, insertar, actualizar y eliminar declaraciones dentro de la aplicación no funcionaría. – tplaner

+0

@evolve, se vuelve más difícil, pero debe leer las vistas actualizables. No sé de la mano si sería posible con sus requisitos, pero creo que sí. –

+0

Esto casi funciona, inserta/actualiza/elimina el trabajo sin problemas, sin embargo, si SELECCIONA las 100 principales * DESDE {tabla}, siempre devuelve las 100 principales superiores, no basa las 100 principales en la consulta que se está ejecutando. A veces tienen declaraciones WHERE dentro de la consulta que necesitan funcionar. Tan cerca, sin embargo. – tplaner

1

Tiene que haber un comando para ello.

Sé en MYSQL que es "LIMIT (firstindex, lastindex)" al final de la instrucción sql.

Creo que he oído en MSSQL puede escribir:

selecciona Superior 10,20 ... o algo así

Eso significaría selecciona 20 filas con 10 principios que creo

1

puede utilizar la parte superior seleccionar

SELECT 50 por ciento superior * FROM Personas (http://www.w3schools.com/sql/sql_top.asp)

o

No la paginación como esto le ayudará a

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,' [email protected] + 
             ' 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 
+3

Parece que no tiene acceso a SQL –

1

Si el cliente usa TCP para conectarse a la base de datos, puede insertar un servidor proxy TCP casi transparente entre el cliente y el servidor de la base de datos en el lado del servidor. A continuación, puede reescribir cualquier consulta que provenga del cliente (utilizando TOP o algún medio para mejorar la consulta).

A continuación, configura SQL Server para que se ejecute en un puerto diferente, inicie su proxy para que se publique en el puerto original y haga que se conecte al servidor SQL en el nuevo puerto. Si conoce la dirección IP de origen del cliente, puede usar el reenvío de puertos para poder dirigirlos al proxy y dejar el servidor de la base de datos configurado tal como está.

Podría escribir y probar esto en una hora, pero requiere cierto conocimiento de la programación del socket.

+0

+1. Como solución ubergeek, esto sería genial. Dudo que sea factible en una hora, pero ciertamente es factible. –

+0

Solución fría, aunque no plausible. – tplaner

+0

@Evolve, he usado esta solución para otros tipos de sistemas de producción. Es cierto que no lo he usado para un sistema de base de datos, pero lo haría. –

0

Puede soltar todos los registros pero X de la tabla y almacenarlos en otro lugar

Cuestiones relacionadas