2008-11-01 27 views
87

Me gustaría construir una consulta que muestre todos los resultados en una tabla, pero se compensa con 5 desde el comienzo de la tabla. Por lo que puedo decir, el LÍMITE de MySQL requiere un límite así como una compensación. ¿Hay alguna manera de hacer esto?Mysql Offset Infinite rows

+1

Esta es una pregunta totalmente válida, pero me pregunto si lo que sería mejor es tomar todo e ignorar los primeros registros programáticamente. Dado el horror de lo que parece ser la mejor respuesta (límite 5, 18446744073709551615), me inclinaría a trabajar en torno a las limitaciones del LIMIT de MySQL. – cesoid

+2

@cesoid que pasa si quieres 'limit 5000, 18446744073709551615'. No va a buscar 5000 filas adicionales solo para que su código se vea bonito. – elipoultorak

+0

@ user3576887 Creo que tienes razón, solo estaba considerando la pregunta anterior con la suposición de que 5 era el único requisito, en lugar de una cantidad variable que podría ser mucho más grande (y en lugar de resolver el problema de otra persona). – cesoid

Respuesta

124

Desde el MySQL Manual on LIMIT:

Para recuperar todas las filas de un determinado compensan hasta el final del conjunto de resultados , puede usar un número grande para el segundo parámetro. Esta declaración recupera todas las filas de la fila 96a de la última:

SELECT * FROM tbl LIMIT 95, 18446744073709551615; 
+83

¡Horrible! Vine aquí esperando que MySQL hiciera la cláusula Limit opcional, tal como es, pero también con una compensación proporcionada ... ¡pero no! He visto este 18446744073709551615 disperso por todo el código y estaba culpando a los programadores perezosos, ¡pero es una característica de diseño! – Petruza

+7

horrible respuesta, pero eso es oficial de MySQL Doc. Lo que puedo decir @ _ @ – GusDeCooL

+16

18446744073709551615 es 2^64-1 para aquellos que se estaban preguntando. Es posible que desee tener cuidado porque no podrá almacenar este valor en un entero de 32 bits. Debe asegurarse de almacenar esto como una cadena para garantizar la compatibilidad. – AlicanC

17

Como usted ha mencionado que se requiere LÍMITE, por lo que necesita para usar el límite más grande posible, que es 18446744073709551615 (máximo de BIGINT sin signo)

SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5 
+24

Guau, ¿es esta la solución oficial del equipo de MySQL? – Antony

3

Otro enfoque sería seleccionar una columna autoimcremented y luego filtrarla usando HAVING.

SET @a := 0; 
select @a:[email protected] + 1 AS counter, table.* FROM table 
HAVING counter > 4 

Pero probablemente me quedo con el enfoque de límite alto.

0

Justo hoy estaba leyendo sobre la mejor manera de obtener grandes cantidades de datos (más de un millón de filas) de una tabla mysql. Una forma es, como se sugiere, usar LIMIT x,y donde x es el desplazamiento y y la última fila que desea devolver. Sin embargo, como descubrí, no es la forma más eficiente de hacerlo. Si tiene una columna de autoincrement, puede usar fácilmente una declaración SELECT con una cláusula WHERE que indique desde qué registro desea comenzar.

Por ejemplo, SELECT * FROM table_name WHERE id > x;

Parece que MySQL se lleva todos los resultados cuando se utiliza LIMIT y sólo muestra los registros que caben en el desplazamiento: no es el mejor para el rendimiento.

Fuente: Responda a esta pregunta MySQL Forums. Solo toma nota, la pregunta tiene alrededor de 6 años.

+8

Esto dará resultados incorrectos si alguna vez borró un registro. Este método es especialmente peligroso porque funciona la mayor parte del tiempo y falla silenciosamente cuando no funciona. – octern

-1

Sé que esto es antiguo, pero no vi una respuesta similar, así que esta es la solución que usaría.

Primero, ejecutaría una consulta de conteo en la tabla para ver cuántos registros existen. Esta consulta es rápida y normalmente el tiempo de ejecución es insignificante. Algo así como:

SELECT COUNT(*) FROM table_name; 

Entonces construiría mi consulta usando el resultado que obtuve de recuento como mi límite (ya que es el número máximo de filas de la tabla podría volver). Algo así como:

SELECT * FROM table_name LIMIT count_result OFFSET desired_offset; 

O, posiblemente, algo así como:

SELECT * FROM table_name LIMIT desired_offset, count_result; 

Por supuesto, si es necesario, se podría restar desired_offset de count_result para obtener un valor real, exacta para suministrar como límite.Pasar el valor "18446744073709551610" simplemente no tiene sentido si realmente puedo determinar un límite apropiado para proporcionar.

+0

select count (*) en una tabla con 7M records toma alrededor de 17s – amd

-5
WHERE .... AND id > <YOUROFFSET> 

id puede ser cualquier columna numérica autoincremented o único que tienes ...

+3

Mala idea. Le dará el desplazamiento incorrecto si alguna vez ha eliminado una fila. – octern

-1

El uso de este otro question y la fusión de ese truco con la respuesta de Greg, puede utilizar ~ 0 en lugar del máximo BIGINT sin signo valor:

SELECT * FROM tbl LIMIT ~0 OFFSET 95; 

o

SELECT * FROM tbl LIMIT 95, ~0; 
+0

Probado esto en MariaDB 10.0 y MySQL 5.6; no funciona –

+0

Es extraño, porque estoy usando esta consulta en MySQL 5.6.25 y funciona. No lo he probado en MariaDB. ¿Me puede dar un ejemplo del problema o algunos detalles del entorno? –

+1

MySQL dice 'sintaxis SQL; revise el manual que corresponde a su versión del servidor MySQL para la sintaxis correcta para usar cerca de '~ 0' ' – Hett

0

puede utilizar un MyS Declaración QL con LIMIT:

START TRANSACTION; 
SET @my_offset = 5; 
SET @rows = (SELECT COUNT(*) FROM my_table); 
PREPARE statement FROM 'SELECT * FROM my_table LIMIT ? OFFSET ?'; 
EXECUTE statement USING @rows, @my_offset; 
COMMIT; 

Probado en MySQL 5.5.44. Por lo tanto, podemos evitar la inserción del número 18446744073709551615.

nota: la transacción se asegura de que la variable @rows esté de acuerdo con la tabla considerada en la ejecución de la declaración.

6

Como se señaló en otras respuestas, MySQL sugiere usar 18446744073709551615 como la cantidad de registros en el límite, pero considere esto: ¿qué haría si obtuviera 18,446,744,073,709,551,615 registros? De hecho, ¿qué harías si obtuvieras 1,000,000,000 de registros?

Quizás desee más de mil millones de registros, pero mi punto es que hay un límite en el número que quiere, y es menos de 18 quintillones. En aras de la estabilidad, la optimización y, posiblemente, la usabilidad, sugeriría poner algún límite significativo a la consulta. Esto también reduciría la confusión para cualquiera que nunca haya visto ese número de apariencia mágica, y tendrá el beneficio adicional de comunicar al menos cuántos registros está dispuesto a manejar a la vez.

Si realmente debe obtener todos los 18 trillones de registros de su base de datos, tal vez lo que realmente quiere es tomarlos en incrementos de 100 millones y repetir 184 mil millones de veces.

+0

Tiene razón, pero mantener esta decisión para el desarrollador no es una buena opción – amd

+0

@amd ¿Podría explicar eso un poco más? No sé lo que estás tratando de decir. – cesoid