¿Por qué utilizar Select 100% superior?

82

Entiendo que antes de SQL Server 2005 , se podía "engañar" a SQL Server para que permitiera el uso de una orden en una definición de vista, al incluir también TOP 100 PERCENTen la cláusula SELECT . Pero he visto otro código que he heredado que usa SELECT TOP 100 PERCENT... dentro de declaraciones SQL dinámicas (usado en ADO en aplicaciones ASP.NET , etc.). Hay alguna razón para esto? ¿No es el resultado el mismo que no incluir el TOP 100 PERCENT?

Ed Schembor
fuente
5
tal vez se esté construyendo una declaración: "SELECCIONE EL {0} PERCENT
PRINCIPAL
Tu primera oración se ha convertido en la respuesta a una de mis preguntas ocultas.
Muhammad Ashikuzzaman
Utilizo el 99,9999999 POR CIENTO superior y siempre funciona. Está lo suficientemente cerca. Tiendo a agregar un número de '9' en función del número esperado de registros. Más discos, más 9 y siempre funciona. He usado SQL 2008 a SQL 2017.
pedi

Respuestas:

51

Se utilizó para " materialización intermedia (búsqueda de Google) "

Buen artículo: Adam Machanic: Explorando los secretos de la materialización intermedia

Incluso planteó un MS Connect para que se pueda hacer de una manera más limpia.

Mi vista "no es intrínsecamente mala", pero no la use a menos que esté 100% seguro. El problema es que solo funciona en el momento en que lo hace y probablemente no más tarde (nivel de parche, esquema, índice, recuento de filas, etc.) ...

Ejemplo resuelto

Esto puede fallar porque no sabe en qué orden se evalúan las cosas

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100

Y esto también puede fallar porque

SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100

Sin embargo, esto no sucedió en SQL Server 2000. La consulta interna se evalúa y se pone en cola:

SELECT foo
FROM
    (SELECT TOP 100 PERCENT foo From MyTable WHERE ISNUMERIC (foo) = 1 ORDER BY foo) bar
WHERE
    CAST(foo AS int) > 100

Tenga en cuenta que esto todavía funciona en SQL Server 2005

SELECT TOP 2000000000 ... ORDER BY...
gbn
fuente
¿Por qué falla la segunda consulta? ¿Porque la consulta interna no se evalúa (necesariamente) completamente?
Kenny Evitt
¡Ese segundo enlace explica por qué la creación de tablas temporales a veces resulta en mejoras dramáticas de rendimiento!
Kenny Evitt
41

TOP (100) PERCENT no tiene ningún significado en las versiones recientes de SQL Server, y el procesador de consultas lo ignora (junto con el ORDER BY correspondiente, en el caso de una definición de vista o tabla derivada).

Tienes razón en que alguna vez podría usarse como un truco, pero incluso entonces no era confiable. Lamentablemente, algunas de las herramientas gráficas de Microsoft incluyen esta cláusula sin sentido.

En cuanto a por qué esto podría aparecer en SQL dinámico, no tengo idea. Tiene razón en que no hay razón para ello, y el resultado es el mismo sin él (y nuevamente, en el caso de una definición de vista o tabla derivada, sin las cláusulas TOP y ORDER BY).

Steve Kass
fuente
Esto no es cierto; consulte este enlace de la respuesta de @gbn para obtener más detalles.
Kenny Evitt
3
El enlace al que hace referencia no dice nada sobre SELECCIONAR EL (100) PORCENTAJE SUPERIOR .. ORDENAR POR, lo cual no tiene sentido. El enlace menciona el uso de SELECT TOP (2147483647) .. ORDER BY. Actualmente, el optimizador de SQL Server eliminará SELECT TOP (100) PERCENT .. ORDER BY, porque no tiene sentido. Esa combinación siempre define la misma colección de filas que SELECT sin TOP / ORDER BY. Actualmente, el optimizador no intenta determinar si 2147483647 comprende todas las filas, por lo que no elimina la combinación TOP - ORDER BY en este caso.
Steve Kass
2
En realidad, el enlace menciona TOP (100) PERCENT: "... Podría intentar forzar la materialización intermedia de la tabla derivada, sin la tabla temporal, usando TOP 100 PERCENT junto con ORDER BY. Desafortunadamente, el equipo del optimizador de consultas de SQL Server decidió que esto no era ' Es una buena idea, y el optimizador ahora ignora esos intentos ". De hecho, te respalda.
Kenny Evitt
Deshacería mi voto negativo si pudiera . [Si edita su respuesta, la
votaré a favor
1
Probablemente estés confundido porque cambié de opinión; mi primer comentario fue incorrecto; tienes razón.
Kenny Evitt
23

... permitir el uso de un ORDER BY en una definición de vista.

Esa no es una buena idea. Una vista nunca debe tener un ORDER BY definido.

Un ORDER BY tiene un impacto en el rendimiento: usarlo como vista significa que ORDER BY aparecerá en el plan de explicación. Si tiene una consulta en la que la vista se une a algo en la consulta inmediata, o se hace referencia a ella en una vista en línea (factorización CTE / subconsulta), el ORDER BY siempre se ejecuta antes del ORDER BY final (asumiendo que se definió). No hay ningún beneficio en ordenar filas que no son el resultado final establecido cuando la consulta no usa TOP (o LIMIT para MySQL / Postgres).

Considerar:

CREATE VIEW my_view AS
    SELECT i.item_id,
           i.item_description,
           it.item_type_description
      FROM ITEMS i
      JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
  ORDER BY i.item_description

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description

... es el equivalente a usar:

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM (SELECT i.item_id,
                 i.item_description,
                 it.item_type_description
            FROM ITEMS i
            JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
        ORDER BY i.item_description) t
ORDER BY t.item_type_description

Esto es malo porque:

  1. El ejemplo es ordenar la lista inicialmente por la descripción del artículo y luego se reordena según la descripción del tipo de artículo. Son recursos desperdiciados en el primer tipo: ejecutarse como está no significa que se esté ejecutando:ORDER BY item_type_description, item_description
  2. No es obvio por qué se ordena la vista debido a la encapsulación. Esto no significa que deba crear varias vistas con diferentes órdenes de clasificación ...
Ponis dios mio
fuente
6

Si no hay una ORDER BYcláusula, entonces TOP 100 PERCENTes redundante. (Como mencionas, este fue el 'truco' con las vistas)

[Con suerte, el optimizador optimizará esto.]

Trigo Mitch
fuente
5

He visto otro código que he heredado que usa SELECT TOP 100 PERCENT

La razón de esto es simple: Enterprise Manager solía intentar ser útil y formatear su código para incluirlo por usted. No tenía sentido intentar quitarlo, ya que realmente no dolía nada y la próxima vez que lo cambiaras, EM lo insertaba de nuevo.

Joel Coehoorn
fuente
4

No hay razón más que indiferencia, supongo.

Estas cadenas de consulta suelen generarse mediante una herramienta de consulta gráfica. El usuario se une a algunas tablas, agrega un filtro, un orden de clasificación y prueba los resultados. Dado que el usuario puede querer guardar la consulta como una vista, la herramienta agrega un TOP 100 POR CIENTO. En este caso, sin embargo, el usuario copia el SQL en su código, parametriza la cláusula WHERE y oculta todo en una capa de acceso a datos. Fuera de la mente, fuera de la vista.

Peter Radocchia
fuente
1

Por favor, pruebe lo siguiente, espero que funcione para usted.

      SELECT TOP
              ( SELECT COUNT(foo) 
                  From MyTable 
                 WHERE ISNUMERIC (foo) = 1) * 
                  FROM bar WITH(NOLOCK) 
              ORDER BY foo
                 WHERE CAST(foo AS int) > 100
               )
Lakshminarayanan E
fuente
1

El error lo dice todo ...

Msg 1033, nivel 15, estado 1, procedimiento TestView, línea 5 La cláusula ORDER BY no es válida en vistas, funciones en línea, tablas derivadas, subconsultas y expresiones de tabla comunes, a menos que también se especifique TOP, OFFSET o FOR XML.

No use TOP 100 PERCENT, useTOP n , donde N es un número

El TOP 100 PERCENT (por razones que no sé) es ignorado por SQL Server VIEW (versiones posteriores a 2012), pero creo que MS lo mantuvo por razones de sintaxis. TOP n es mejor y funcionará dentro de una vista y la ordenará de la manera que desee cuando se use una vista inicialmente, pero tenga cuidado .

Fandango68
fuente
0

Supongo que puede usar una variable en el resultado, pero además de obtener la pieza ORDER BY en una vista, no verá un beneficio al indicar implícitamente "TOP 100 PERCENT":

declare @t int
set @t=100
select top (@t) percent * from tableOf
Lauren Glenn
fuente
2
La cuestión Why use Select Top 100 Percentno es obtener un recuento variable para el porcentaje.
Bummi
0

Intente esto, lo explica bastante por sí mismo. No puede crear una vista con un ORDER BY excepto si ...

CREATE VIEW v_Test
         AS
           SELECT name
             FROM sysobjects
         ORDER BY name
        GO

Msg 1033, nivel 15, estado 1, procedimiento TestView, línea 5 La cláusula ORDER BY no es válida en vistas, funciones en línea, tablas derivadas, subconsultas y expresiones de tabla comunes, a menos que también se especifique TOP, OFFSET o FOR XML.

John Brewster
fuente