1) Har du ett index på buyerEmail kolumnen? Det känns ju som att den kört linjärsökning iom att det gått så långsamt..
CREATE INDEX ordertable_buyeremail_idx ON OrderTable (buyerEmail);
2) Du kan ju testa köra DISTINCT(buyerEmail) i subqueryn.. Blir ju ett mindre dataset i subqueryn, men den måste ju dock då beräknas innan användning, så gissningsvis bir det inte någon prestandavinst.
3) Du kan överväga att bryta ut buyerEmail till en egen tabell (som sedan då länkas ihop av OrderTable med en foreign key). Fördelen skulle ju isf vara att mail kolumnen skulle kunna vara UNIQUE..
Om det är viktigt att OrderTable ser ut exakt som den gör nu skulle du isf kunna wrappa den via en VIEW..
EDIT:
Förresten, du säger att det fungerar perfekt men att det är segt.. Men fungerar det verkligen?
Tycker mig ana att det inte borde fungera alls..
Matchar inte subqueryn alltid mot sig själv? (Då varje rad du jämför för kommer att ha sin mailaddress i subquery settet)
Borde väl behöva en WHERE som excluderar den egna raden, så typ:
SELECT COUNT(*) FROM OrderTable WHERE approveDate>2011-01-01 AND approveDate<2011-01-10 AND buyerEmail IN (SELECT buyerEmail FROM OrderTable as t WHERE OrderTable.id != t.id) as t2;
Och måste ändå köra sånna där conditions så kan man väl lika gärna köra på din variant, borde väl vara rätt mycket snabbare då subqueryn blir statisk för alla rader, istället för som ovan då IN-queryn blir unik för alla (en bra optimerara lär väl kunna fixa en hel del iof))
a) SELECT count(*) FROM (SELECT COUNT(*) as c FROM OrderTable WHERE approveDate>2011-01-01 AND approveDate<2011-01-10 GROUP BY buyerEmai) as t WHERE t.c=1;
b) SELECT count(*) FROM (SELECT COUNT(*) as c FROM OrderTable WHERE approveDate>2011-01-01 AND approveDate<2011-01-10 GROUP BY buyerEmai) as t WHERE t.c>1;
EDIT2:
Nä vänta, det där har ju samma problem som du haft tidigare.. Testa detta istället
a)
SELECT count(*) FROM
OrderTable
JOIN (SELECT buyerEmail,COUNT(*) as c FROM OrderTable GROUP BY buyerEmail) as t
ON t.buyerEmail=buyerEmail
WHERE
t.c=1
AND approveDate>2011-01-01
AND approveDate<2011-01-10;
Så lite sanity-check.
Hämtar en lista av buyerEmail och förekomster, joinar med OrderTable.
OrderTable har nu kolumnen c som betäcknar hur många ordrar kunden har..
En rad inom ett visst approveDate interval är därmed för en ny kund om c=1, och för en återkommande kund om c>1.
Verkar stämma tycker jag.
Då du joinar på buyerEmail så är det ju trevligt om du kör den indexerat..
Tredje gången gillt?