Reputation: 559
I have today a database with 3 queries for statistics in testcases. I use php to build a website but the queries takes too long to execute, so I cannot show the complete site statistics as I wan't to do. As it is now the database is updated rarely in batches so I could make events that updates the databases daily / weekly for this purpose.
I have the following 3 queries today to display the information I want:
SELECT key FROM testcase GROUP BY key;
This gives me a list with int from 4-10 groups of tests. say 1,2,3,4 for the case of argument. I then iterate this in the subqueries as key to get the number of tests passed and number of tests not passed with the following 2 queries:
SELECT COUNT(*) AS passed FROM testcase INNER JOIN testcases ON
testcase.ID = testcases.testcaseid WHERE pass = 1 AND key = %value%;
and
SELECT COUNT(*) AS failed FROM testcase INNER JOIN testcases ON
testcase.ID = testcases.testcaseid WHERE pass = 0 AND key = %value%;
this is how it works today. The queries takes around 25-30 seconds for each key and that makes the site timeout. (%value% is pseudo code for the current value from the for loop)
Instead I was thinking of a sql query that added this to a database table that consists of key,pass,fail tables that i populate daily/weekly to show on the site as statistics. I have seen some cases where you can iterate with a subquery but as the 2 executed queries is opposites I cannot see any solution for this.
I have tried indexing the values I use in the queries with no success (which could be wrong as well).
// Andreas (SQL novice)
Edit:
Oh the dilemma, where to set the solution, I made a combine from Gordon and Joe to make the fastest query that worked like a charm:
INSERT INTO statistics (key,passed,failed)
SELECT
key,
SUM(case when T.pass = 1 then T.matches else 0 end) as passed,
SUM(case when T.pass = 0 then T.matches else 0 end) as failed
FROM
(SELECT
key,pass,COUNT(*) AS matches
FROM testcase INNER JOIN testcases ON
testcase.ID = testcases.testcaseid
GROUP BY key,pass)T
GROUP BY key
Upvotes: 1
Views: 588
Reputation: 1269773
I think you should do this all with one query, that returns the key and the information you want:
select key,
SUM(case when pass = 1 AND key = %value% then 1 else 0 end) as passed,
SUM(case when pass = 0 AND key = %value% then 1 else 0 end) as failed
from testcase INNER JOIN testcases ON
testcase.ID = testcases.testcaseid
group by key
To the extent possible, you should let the database do the "iterations" and just read back the resulting data.
In response to your comment. If you have a list of keys in $VALUE, then you could do:
insert into statistics(key, pass, fail)
select key,
SUM(case when pass = 1 then 1 else 0 end) as passed,
SUM(case when pass = 0 then 1 else 0 end) as failed
from testcase INNER JOIN testcases ON
testcase.ID = testcases.testcaseid
where concat(',', $VALUE, ',') like concat('%', key, '%')
group by key
Or, if you are generating the query, you can put the list in an in
clause. So, the where
could look like:
where key in (2, 3, 4, 5)
Upvotes: 1
Reputation: 27247
Try:
select key, pass, count(*) from testcase group by key, pass
An index on pass
is going to be useless. Index on key
, that should help a little. But with a cardinality of 4-10, meh, not going to be super helpful.
Upvotes: 1