I am not sure on how to begin optimizing this High Latency SQL query that my platform runs. Other than reducing the datasets, what are some things that I can do?
SELECT ctm.*
FROM compound_transaction_map ctm
JOIN bustransaction_map btm ON ctm.transId = btm.transId
WHERE btm.docId = ?
docId gets inserted by my DBWConnector in the Java code
The main issue the size of the tables, compound_transaction_map is 776,387 entries and bustransaction_map is 3,252,772. I am working on reducing the table sizes, but just wondering if this query is also an issue.
Just looking to get some insight from someone more experienced than me. I appreciate your help.
Edit: There are indexes on transId and bustransaction_map.docID
mysql> show index from compound_transaction_map;
+--------------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| compound_transaction_map | 0 | PRIMARY | 1 | id | A | 765804 | NULL | NULL | | BTREE | | |
| compound_transaction_map | 0 | UNQ_compoundId_transId | 1 | transId | A | 772560 | NULL | NULL | | BTREE | | |
| compound_transaction_map | 0 | UNQ_compoundId_transId | 2 | compoundId | A | 772560 | NULL | NULL | | BTREE | | |
| compound_transaction_map | 1 | transId | 1 | transId | A | 772560 | NULL | NULL | | BTREE | | |
| compound_transaction_map | 1 | compoundId | 1 | compoundId | A | 645871 | NULL | NULL | | BTREE | | |
| compound_transaction_map | 1 | companyId | 1 | companyId | A | 625 | NULL | NULL | | BTREE | | |
+--------------------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
mysql> show index from bustransaction_map;
+--------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| bustransaction_map | 0 | PRIMARY | 1 | id | A | 2869993 | NULL | NULL | | BTREE | | |
| bustransaction_map | 0 | docId | 1 | docId | A | 2883521 | NULL | NULL | YES | BTREE | | |
| bustransaction_map | 1 | transId | 1 | transId | A | 1019639 | NULL | NULL | YES | BTREE | | |
+--------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
mysql> EXPLAIN
-> SELECT ctm.*
IN bustransaction_ma -> FROM compound_transaction_map ctm
-> JOIN bustransaction_map btm ON ctm.transId = btm.transId
-> WHERE btm.docId = '62EFCD90-BC62-9984-0B20-4465528D6359';
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
| 1 | SIMPLE | btm | NULL | const | docId,transId | docId | 153 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | ctm | NULL | ALL | NULL | NULL | NULL | NULL | 772560 | 100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
mysql> SHOW CREATE TABLE compound_transaction_map;
+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| compound_transaction_map | CREATE TABLE `compound_transaction_map` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`compoundId` varchar(100) NOT NULL,
`transId` varchar(100) NOT NULL,
`companyId` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `UNQ_compoundId_transId` (`transId`,`compoundId`),
KEY `transId` (`transId`),
KEY `compoundId` (`compoundId`),
KEY `companyId` (`companyId`)
) ENGINE=InnoDB AUTO_INCREMENT=865326 DEFAULT CHARSET=latin1 |
+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SHOW CREATE TABLE bustransaction_map;
+--------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bustransaction_map | CREATE TABLE `bustransaction_map` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`transId` varchar(50) DEFAULT NULL,
`docId` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `docId` (`docId`),
KEY `transId` (`transId`)
) ENGINE=InnoDB AUTO_INCREMENT=13033253 DEFAULT CHARSET=utf8 |
+--------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> EXPLAIN select ctm.* from bustransaction_map btm join compound_transaction_map ctm force index (transId) on ctm.transId = btm.transId where btm.docId = '62EFCD90-BC62-9984-0B20-4465528D6359';
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
| 1 | SIMPLE | btm | NULL | const | docId,transId | docId | 153 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | ctm | NULL | ALL | NULL | NULL | NULL | NULL | 772560 | 100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+--------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
2
Answers
MySQL can only use one index per table. The
explain
shows that it chose to use the index onbustransaction_map.docId
to help with thewhere docId = ?
; bustransaction_map is the larger table so it wants to cut down its rows. It uses no index oncompound_transaction_map
.To solve this, create a compound index on bustransaction_map of
(docId, transId)
(the order is important). MySQL can use this index for any queries which feature justbustransaction_map.docId
and queries which use bothbustransaction_map.docId
andbustransaction_map.transId
like yours.You can then drop the index on
docId
, it’s redundant. You can also drop the single column index oncompound_transaction_map.transId
, it is redundant with the compound index on(transId, compoundId)
.In general, if you have two columns you can cover all queries containing any combination of them with two indexes…
More notes:
varchar(255)
. "varchar" means "variable [size] characters"; MySQL will only use as much space as it needs. Arbitrary restrictions just cause future headaches.You can try
I think, for subquery will be used index (docId) – index seek, or (docId,transId) – only index scan.
For join will be used
range join
with index on ctm.transId.