¿Por qué necesita soporte instrumental para la paginación de claves?

¡Hola a todos! Soy un desarrollador backend que escribe microservicios en Java + Spring. Trabajo en uno de los equipos internos de desarrollo de productos de Tinkoff.

¿Por qué necesita soporte instrumental para la paginación de claves?

En nuestro equipo surge a menudo la cuestión de optimizar las consultas en un DBMS. Siempre quieres ser un poco más rápido, pero no siempre puedes arreglártelas con índices cuidadosamente construidos; tienes que buscar algunas soluciones. Durante uno de estos paseos por la web en busca de optimizaciones razonables al trabajar con bases de datos, encontré El blog infinitamente útil de Marcus Wynand, autor de Explicación del rendimiento de SQL. Este es ese raro tipo de blog en el que puedes leer todos los artículos seguidos.

Me gustaría traducirle un breve artículo de Marcus. Hasta cierto punto se le puede llamar un manifiesto que busca llamar la atención sobre el antiguo, pero aún relevante, problema de realizar la operación de compensación según el estándar SQL.

En algunos lugares complementaré al autor con explicaciones y comentarios. Me referiré a todos esos lugares como "aprox." para mayor claridad

Una pequeña introducción

Creo que mucha gente sabe lo problemático y lento que es trabajar con selecciones de página mediante desplazamiento. ¿Sabías que se puede sustituir fácilmente por un diseño más eficiente?

Entonces, la palabra clave offset le dice a la base de datos que omita los primeros n registros de la solicitud. Sin embargo, la base de datos aún necesita leer estos primeros n registros del disco, en el orden dado (nota: aplique la clasificación si se especifica), y solo entonces será posible devolver registros desde n+1 en adelante. Lo más interesante es que el problema no está en la implementación específica en el DBMS, sino en la definición original según el estándar:

…las filas se ordenan primero según el y luego limitado eliminando el número de filas especificadas en el desde el principio…
-SQL:2016, Parte 2, 4.15.3 Tablas derivadas (nota: actualmente el estándar más utilizado)

El punto clave aquí es que el desplazamiento toma un único parámetro: el número de registros a omitir, y eso es todo. Siguiendo esta definición, el DBMS sólo puede recuperar todos los registros y luego descartar los innecesarios. Obviamente, esta definición de compensación nos obliga a hacer un trabajo extra. Y ni siquiera importa si es SQL o NoSQL.

Sólo un poco más de dolor

Los problemas con la compensación no terminan ahí y aquí le explicamos por qué. Si, entre la lectura de dos páginas de datos del disco, otra operación inserta un nuevo registro, ¿qué pasará en este caso?

¿Por qué necesita soporte instrumental para la paginación de claves?

Cuando se usa el desplazamiento para omitir registros de páginas anteriores, en la situación de agregar un nuevo registro entre lecturas de diferentes páginas, lo más probable es que obtenga duplicados (nota: esto es posible cuando leemos página por página usando la construcción ordenar por, luego en medio de nuestra salida puede obtener una nueva entrada).

La figura muestra claramente esta situación. La base lee los primeros 10 registros, después de lo cual se inserta un nuevo registro, que compensa todos los registros leídos en 1. Luego, la base toma una nueva página de los siguientes 10 registros y no comienza desde el 11, como debería, sino desde el 10, duplicando este registro. Existen otras anomalías asociadas con el uso de esta expresión, pero esta es la más común.

Como ya hemos descubierto, estos no son problemas de un DBMS específico o de sus implementaciones. El problema está en definir la paginación según el estándar SQL. Le decimos al DBMS qué página buscar o cuántos registros omitir. La base de datos simplemente no puede optimizar dicha solicitud, ya que hay muy poca información para ello.

También vale la pena aclarar que esto no es un problema de una palabra clave específica, sino de la semántica de la consulta. Hay varias sintaxis más que son idénticas en su naturaleza problemática:

  • La palabra clave offset es la mencionada anteriormente.
  • Una construcción de dos palabras clave límite [compensación] (aunque el límite en sí no es tan malo).
  • Filtrado por límites inferiores, basado en la numeración de filas (por ejemplo, número_fila(), número de fila, etc.).

Todas estas expresiones simplemente le indican cuántas líneas debe omitir, sin información ni contexto adicional.

Más adelante en este artículo, la palabra clave offset se utiliza como resumen de todas estas opciones.

La vida sin COMPENSACIÓN

Ahora imaginemos cómo sería nuestro mundo sin todos estos problemas. Resulta que la vida sin desplazamiento no es tan difícil: con una selección podemos seleccionar solo aquellas filas que aún no hemos visto (nota: es decir, aquellas que no estaban en la página anterior), usando una condición en donde.

En este caso, partimos del hecho de que las selecciones se ejecutan en un conjunto ordenado (el viejo orden por). Como tenemos un conjunto ordenado, podemos usar un filtro bastante simple para obtener solo los datos que están detrás del último registro de la página anterior:

    SELECT ...
    FROM ...
    WHERE ...
    AND id < ?last_seen_id
    ORDER BY id DESC
    FETCH FIRST 10 ROWS ONLY

Ese es el principio completo de este enfoque. Por supuesto, las cosas se vuelven más divertidas cuando se ordenan por muchas columnas, pero la idea sigue siendo la misma. Es importante señalar que este diseño es aplicable a muchos NoSQL-decisiones.

Este enfoque se denomina método de búsqueda o paginación de conjunto de claves. Resuelve el problema del resultado flotante (nota: la situación de escritura entre lecturas de página descrita anteriormente) y, por supuesto, lo que a todos nos encanta, funciona más rápido y más estable que el desplazamiento clásico. La estabilidad radica en el hecho de que el tiempo de procesamiento de la solicitud no aumenta en proporción al número de la tabla solicitada (nota: si desea obtener más información sobre el trabajo de los diferentes enfoques de paginación, puede mirar la presentación del autor. Allí también encontrará puntos de referencia comparativos para diferentes métodos).

una de las diapositivas habla de esoEsa paginación por claves, por supuesto, no es omnipotente: tiene sus limitaciones. Lo más significativo es que no tiene la capacidad de leer páginas aleatorias (nota: de manera inconsistente). Sin embargo, en la era del desplazamiento sin fin (nota: en la parte frontal), esto no es un problema. De todos modos, especificar un número de página para hacer clic es una mala decisión en el diseño de la interfaz de usuario (nota: opinión del autor del artículo).

¿Qué pasa con las herramientas?

La paginación por claves a menudo no es adecuada debido a la falta de soporte instrumental para este método. La mayoría de las herramientas de desarrollo, incluidos varios marcos, no le permiten elegir exactamente cómo se realizará la paginación.

La situación se ve agravada por el hecho de que el método descrito requiere soporte de extremo a extremo en las tecnologías utilizadas, desde el DBMS hasta la ejecución de una solicitud AJAX en el navegador con desplazamiento sin fin. En lugar de especificar solo el número de página, ahora debe especificar un conjunto de claves para todas las páginas a la vez.

Sin embargo, la cantidad de marcos que admiten la paginación de claves está creciendo gradualmente. Esto es lo que tenemos en este momento:

(Nota: algunos enlaces se eliminaron debido a que en el momento de la traducción algunas bibliotecas no se habían actualizado desde 2017-2018. Si está interesado, puede consultar la fuente original).

Es en este momento que se necesita tu ayuda. Si desarrolla o admite un marco que hace uso de la paginación, entonces le pido, le insto y le imploro que proporcione soporte nativo para la paginación en claves. Si tienes preguntas o necesitas ayuda, estaré encantado de ayudarte (foro, Twitter, Formulario de contacto) (nota: por mi experiencia con Marcus, puedo decir que está muy entusiasmado con difundir este tema).

Si utiliza soluciones listas para usar que cree que son dignas de tener soporte para paginación por claves, cree una solicitud o incluso ofrezca una solución lista para usar, si es posible. También puedes enlazar a este artículo.

Conclusión

La razón por la que un enfoque tan simple y útil como la paginación por claves no está muy extendido no es que sea difícil de implementar técnicamente o requiera un gran esfuerzo. La razón principal es que muchos están acostumbrados a ver y trabajar con offset; este enfoque lo dicta la propia norma.

Como resultado, pocas personas piensan en cambiar el enfoque de la paginación y, debido a esto, el soporte instrumental de los marcos y bibliotecas se está desarrollando mal. Por lo tanto, si la idea y el objetivo de la paginación sin offset está cerca de ti, ¡ayúdanos a difundirla!

Fuente: https://use-the-index-luke.com/no-offset
Autor: Markus Winand

Fuente: habr.com

Añadir un comentario