2011-02-17 21 views
20

Tengo una consulta para encontrar ciertos clientes de una tabla.Optimización de SELECT COUNT para EXISTS

SELECT COUNT(*) 
    FROM CUSTOMER 
WHERE amount <> 0 
    AND customerid = 22 

Hay un índice en idcliente, por lo que la base de datos escanea todas las filas con idcliente = 22.

Puesto que el resultado es procesada mediante la comprobación de si el recuento devuelve cero o mayor que cero, ¿cómo puedo optimizar ¿la consulta? Es decir. de tal manera que en la primera fila del cliente con la cantidad <> 0 la consulta devuelve 0 si todas las demás filas son = 0, y luego volver 1.

+0

Relacionado: http://stackoverflow.com/questions/2759756/is-it-possible-to-select-exists-directly-as-a-bit – RQDQ

+0

Primera fila de clientes basada en qué - fecha? –

Respuesta

27
select case 
     when exists (select * 
         from customer 
         where amount <> 0 
          and customerid = 22) then 1 
     else 0 
     end as non_zero_exists 
+3

+1 para usar el formulario de consulta en lugar de IF – RichardTheKiwi

+3

¿Sería más eficiente reemplazar 'seleccionar *' con 'seleccionar customerid' o quizás 'seleccionar 1'? –

+3

@Carlo - no, no lo haría – RichardTheKiwi

6

primer índice en idcliente y la cantidad

CREATE INDEX customer_idx ON customer(customerid, amount); 

vuelva a grabar su consulta como

IF EXISTS (SELECT customerid 
    FROM customer 
    WHERE amount > 0 -- I am assuming here that amount cannot be a negative number. 
    AND customerid = 22) 
    SELECT 1 
ELSE 
    SELECT 0 

Esto debería dar como resultado una búsqueda de índice en customer_idx. De lo contrario, deberá escanear todas las filas para ese cliente (lo que su pregunta parece implicar podría ser mucho).

+1

+1 la solución a * cada * pregunta de rendimiento de SQL es ante todo crear un índice apropiado. –

+2

@Chris esto produce 'Existe sintaxis incorrecta cerca de la palabra clave 'aunque el bit de índice es bueno –

+0

Lo sentimos, fue la codificación en la ventana SO, siempre una mala decisión. Actualizado para usar algo más como su consulta. +1 a tu respuesta. –

3

Parece bastante sencillo

IF EXISTS (SELECT customerid 
      FROM customer 
      WHERE amount <> 0 
        and customerid = 22)) 
    SELECT 1 
ELSE 
    SELECT 0 
2

Una alternativa a EXISTE

select ISNULL((select TOP 1 1 
       from customer 
       where amount <> 0 
       and customerid = 22),0) 

ya he asumido que va a tener un índice en (idcliente) o mejor (idcliente, cantidad).

Cuestiones relacionadas