2009-01-17 9 views

Respuesta

7

¿Tal vez sería mejor con otra forma de realizar su consulta?

Le sugiero que cargue los valores de coincidencia en una tabla de una sola columna, y luego junte internamente la columna que se consulta con la columna individual de la tabla nueva.

En lugar de

SELECT a, b, c FROM t1 WHERE d in (d1, d2, d3, d4, ...) 

construir una tabla temporal con 1 columna, lo llaman "dval"

 
dval 
---- 
d1 
d2 
d3 
SELECT a, b, c FROM t1 
INNER JOIN temptbl ON t1.d = temptbl.dval 
+0

Gracias. También estamos planeando la misma solución para el problema. Sin embargo, agregar una nueva tabla en las instalaciones existentes, necesitará algunas validaciones adicionales y tiempo - Por lo tanto, como una solución temporal pensamos en dividir la consulta. –

+0

No lo recuerdo seguramente, pero creo que una tabla temporal no requeriría mucho en términos de permisos, ya que ocurre transitoriamente en tempdb.Pero a corto plazo, espero que funcionar en lo que usted ha determinado es un recuento de argumentos aceptable. – dkretz

+0

O si los necesita todos a la vez, podría hacer una UNIÓN en las declaraciones múltiples. – dkretz

4

tener que pedir acerca de los límites cuando sea haciendo una consulta SQL o el diseño de base de datos es un buen indicador de que lo estás haciendo mal.

+0

@PhoenixRedeemer Sí, estoy de acuerdo en que mi enfoque es incorrecto. Cambiar el diseño completo llevará algo de tiempo, así que pensé que alguna solución temporal podría resolver el problema –

0

He usado IN con listas bastante grandes de ID. Sospecho que el problema de memoria no está en la consulta en sí. ¿Cómo estás recuperando los resultados?

Esta consulta, por ejemplo, es de un sitio vivo:

SELECT DISTINCT c.id, c.name FROM categories c 
LEFT JOIN product_categories pc ON c.id = pc.category_id 
LEFT JOIN products p ON p.id = pc.product_id 
WHERE p.location_id IN (
955,891,901,877,736,918,900,836,846,914,771,773,833, 
893,782,742,860,849,850,812,945,775,784,746,1036,863, 
750,763,871,817,749,838,986,794,867,758,923,804,733, 
949,808,837,741,747,954,939,865,857,787,820,783,760, 
911,745,928,818,887,847,978,852 
) ORDER BY c.name ASC 

Mi primer paso en el código es terriblemente ingenuo y hay alrededor de 10 de estas consultas en una sola página y la base de datos no parpadea .

Podría, por supuesto, estar ejecutando una lista de 100k valores, lo que sería una historia completamente diferente.

+1

@tobyhede: incluso en nuestro caso, la consulta funciona bien para pequeños conjuntos de datos. Me enfrenté a este problema de memoria cuando el recuento estaba por encima de 4K. –

0

No sé cuál es el límite, pero también he tenido este problema antes. Tenía que volver a escribir mi pregunta algo como esto:

select * from foo 
    where id in (select distinct foo_id from bar where ...) 
2

Yo sólo uso cada vez y no en modo cuando la condición es muy pequeño (menos de 100 filas más o menos). Funciona bien en esos escenarios. Uso una OUTER JOIN cuando la condición es grande ya que la consulta no tiene que buscar la condición "IN" para cada tupla. Solo tiene que verificar la tabla de la que quiere que vengan todas las filas.

Por "IN" la condición de unión no es NULL

por "no IN" la condición de unión IS NULL

por ejemplo

/* Get purchase orders that have never been rejected */ 
SELECT po.* 
FROM PurchaseOrder po LEFT OUTER JOIN 
    (/* Get po's that have been rejected */ 
    SELECT po.PurchaesOrderID 
    FROM PurchaseOrder po INNER JOIN 
     PurchaseOrderStatus pos ON po.PurchaseOrderID = pos.PurchaseOrderID 
    WHERE pos.Status = 'REJECTED' 
    ) por ON po.PurchaseOrderID = por.PurchaseOrderID 
WHERE por.PurchaseOrderID IS NULL /* We want NOT IN */ 
0

I "m con un problema similar, pero sólo pasar 100 3 identificadores de dígitos en mi cláusula IN. Cuando miro el seguimiento de la pila, lo que realmente le corta los valores separados por comas en la cláusula IN. I don' me sale un error, simplemente no obtengo todos los resultados para devolver. ¿Alguien ha tenido un problema como este antes? Si es relevante, estoy usando el framework de Symfony ... Estoy comprobando si es un impulso problema pero solo quería ver si podría ser sql

Cuestiones relacionadas