I am having a problem with this SQL query on mysql that runs for 5 seconds to fetch only 25 records-pretty bad;
select t.* from table1 t
left join table2 t2 on t.id=t2.transaction_id
where t2.transaction_id is null
and t.custom_type =0 limit 25
All the 3 tables have an estimate of 10 million records each.
The structure of the affected tables;
table1 ;
+---------------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| loan_application_id | int(11) | YES | MUL | NULL | |
| loan_repayment_id | int(11) | YES | MUL | NULL | |
| person_id | int(11) | YES | MUL | NULL | |
| direction | tinyint(4) | NO | | NULL | |
| amount | float | NO | | NULL | |
| sender_phone | varchar(32) | YES | MUL | NULL | |
| recipient_phone | varchar(32) | YES | MUL | NULL | |
| sender_name | varchar(128) | YES | | NULL | |
| recipient_name | varchar(128) | YES | | NULL | |
| date_time | datetime | NO | MUL | NULL | |
| local_date_time | datetime | YES | | NULL | |
| payment_method | varchar(128) | YES | | NULL | |
| project | varchar(30) | YES | MUL | NULL | |
| confirmation_number | varchar(64) | YES | MUL | NULL | |
| reversal_of | varchar(32) | YES | | NULL | |
| custom_type | int(11) | YES | | 0 | |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------------------+--------------+------+-----+-------------------+----------------+
table2;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| transaction_id | int(11) | YES | MUL | NULL | |
| type | int(11) | NO | MUL | NULL | |
| phone_number | varchar(16) | NO | MUL | NULL | |
| amount | double | NO | | NULL | |
| description | text | YES | | NULL | |
| person_id | int(11) | YES | MUL | NULL | |
| loan_application_id | int(11) | YES | MUL | NULL | |
| repayment_id | int(11) | YES | | NULL | |
| date_time | datetime | YES | | NULL | |
| local_date_time | datetime | YES | | NULL | |
| last_modified_by | varchar(32) | YES | | NULL | |
| last_modified | timestamp | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
table3;
+--------------------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| transaction_type_id | int(11) | NO | MUL | NULL | |
| msisdn | varchar(32) | NO | MUL | NULL | |
| amount | float | NO | | NULL | |
| mobile_money_provider_id | int(11) | YES | | NULL | |
| mobile_money_provider_code | varchar(32) | YES | | NULL | |
| source_external_id | varchar(128) | YES | | NULL | |
| source_user_id | int(11) | YES | | NULL | |
| payment_server_trx_id | varchar(64) | YES | MUL | NULL | |
| customer_receipt | varchar(64) | YES | MUL | NULL | |
| transaction_account_ref_number | varchar(64) | YES | | NULL | |
| status | int(11) | YES | | NULL | |
| mno_status | int(11) | YES | | NULL | |
| mno_status_desc | text | YES | | NULL | |
| mno_transaction_id | varchar(64) | YES | | NULL | |
| date_completed | timestamp | YES | | NULL | |
| date_acknowledged | timestamp | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| project | varchar(32) | NO | | NULL | |
| loan_application_id | int(11) | YES | MUL | NULL | |
+--------------------------------+--------------+------+-----+---------+-------+
I have already indexed table1(id,custom_type,confirmation_number) table2(transaction_id) table3(customer_receipt) without any significant improvements.
How can i bring down the execution time of this query to below 100 ms?
SHOW CREATE TABLE, it is more descriptive thanDESCRIBE.