Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing SELECT COUNT to EXISTS

I have a query to find certain customers from a table.

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

There is an index on customerid, so the DB scans all rows with customerid = 22.

Since the result is processed by checking whether the count returns zero or more than zero, how can I optimize the query? I.e. such that at the first customer row with amount <> 0 the query returns 0 else if all rows are = 0, then return 1.

like image 916
Carlo V. Dango Avatar asked Feb 17 '11 16:02

Carlo V. Dango


People also ask

How do I optimize a select count query?

The easy fix to see improvement would be add an index on the table on the userID, if you intend to use the userID filter very often in your queries. Of course that if userID is the primary key of your table, the index would not be necessary and maybe other ways to improve needs to be checked.

Why exists () is faster than Count ()?

Answer: Using the T-SQL EXISTS keyword to perform an existence check is almost always faster than using COUNT(*). EXISTS can stop as soon as the logical test proves true, but COUNT(*) must count every row, even after it knows one row has passed the test.

Which is faster count (*) or count column?

The simple answer is no – there is no difference at all. The COUNT(*) function counts the total rows in the table, including the NULL values.

Which is faster in or exists?

EXISTS Is Faster in Performance than IN.


2 Answers

select case          when exists (select *                       from   customer                       where  amount <> 0                              and customerid = 22) then 1          else 0        end  as non_zero_exists 
like image 75
Martin Smith Avatar answered Sep 26 '22 08:09

Martin Smith


First index on customerid and amount

CREATE INDEX customer_idx ON customer(customerid, amount);  

then rewrite your query as

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 

This should result in an index seek on customer_idx. Otherwise you'll need to scan all rows for that customer (which your question seems to imply could be a lot).

like image 43
Chris Shain Avatar answered Sep 25 '22 08:09

Chris Shain