Optimizing a query that selects from a select query

Viewed 23

I am trying to count all suspicious deposits from my app.

The query basically selects, counts and groups the results from an inner select query.

Using this query:

SELECT *, count(id) as repeated from (
    SELECT id, userAccount_id, `change_value_amount`,`change_value_currency_code`, JSON_EXTRACT(details, '$.depositId') as depositId From billing.transactions WHERE type_value = 'DEPOSIT_MADE'
) as q1 
where depositId is not null group by depositId having repeated > 1

Now, this query's execution time is 4-6 secs, which is really annoying.

I also tried creating a temporary table and do the outer where clause based from the temp table:

create temporary table if not exists susDeposit as (SELECT id, userAccount_id, `change_value_amount`,`change_value_currency_code`, JSON_EXTRACT(details, '$.depositId') as depositId From billing.transactions WHERE type_value = 'DEPOSIT_MADE');

select id, userAccount_id, change_value_amount, change_value_currency_code, depositId, count(*) as repeated  from susDeposit
where depositId is not null group by depositId having repeated > 1

in workbench, it executes at 1sec max.

but using pdo, it executes at 5secs, idk the reason why the execution time is different in workbench and pdo.

Code is:

$tempTable = "CREATE TEMPORARY TABLE IF NOT EXISTS susDeposit as (SELECT id, userAccount_id, `change_value_amount`,`change_value_currency_code`, JSON_EXTRACT(details, '$.depositId') as depositId From billing.transactions WHERE type_value = 'DEPOSIT_MADE');";
        $finalSelect = "SELECT id, userAccount_id, change_value_amount, change_value_currency_code, depositId, count(*) as repeated  from susDeposit
        where depositId is not null group by depositId having repeated > 1";

        $query = $this->pdo->query($tempTable);
        $query = $this->pdo->query($finalSelect);
        $query->execute();
        $r = $query->fetch();

Is there any way to optimize this query?

1 Answers

Start by not hiding columns that you need to test on inside JSON strings.

That is, when building the table, put depositId in its own column to help the Optimizer perform the query.

Once you have made that change and provided SHOW CREATE TABLE, I'll help you make a suitable composite index (if needed).

Related