I have two tables. search has 89000 records and email_leads has 26000.
I would like to correlate which email and name has performed the search by left joining on the base_id column from the search table.
However when I include the LEFT JOIN in the query it takes upwards of 7+ minutes plus. When i remove it, the query executes instantly. Is there any way to restructure the query so that it doesn't take that long. The explain output makes me think mysql is actually joining all the rows it is scanning from the search table with the email_leads table instead of just the 10 records i am looking to return from the search table.
Here is the query i am running:
SELECT
sh.base_id,
sh.client_id,
sh.app_id,
sh.result_cnt,
sh.search_type,
sh.min_price,
sh.max_price,
sh.bedrooms,
sh.bathrooms,
sh.neighborhoods,
sh.office_connector,
sh.created,
any_value(el.from_email) as email,
any_value(el.from_name) as name
FROM search AS sh
LEFT JOIN email_leads AS el ON(sh.base_id = el.base_id)
WHERE date(sh.created) >= '2022-04-27'
AND date(sh.created) <= '2022-05-27'
GROUP BY sh.app_id, sh.base_id, sh.client_id, sh.result_cnt, sh.search_type, sh.min_price, sh.max_price,
sh.bedrooms, sh.bathrooms, sh.neighborhoods, sh.office_connector, sh.created ORDER BY sh.created DESC LIMIT 0, 10
Here are the indexes for both tables:
mysql> show index from search;
+--------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-------------------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-------------------------+
| search | 0 | PRIMARY | 1 | id | A | 87659 | NULL | NULL | | BTREE | | | YES | NULL |
| search | 1 | app_id_index | 1 | app_id | A | 5 | NULL | NULL | | BTREE | | | YES | NULL |
| search | 1 | search_type_index | 1 | search_type | A | 3 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | office_connector_index | 1 | office_connector | A | 6 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | bedrooms_index | 1 | bedrooms | A | 53 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | bathrooms_index | 1 | bathrooms | A | 5 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | min_price_index | 1 | min_price | A | 33 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | max_price_index | 1 | max_price | A | 51 | NULL | NULL | YES | BTREE | | | YES | NULL |
| search | 1 | base_id_index | 1 | base_id | A | 5474 | NULL | NULL | | BTREE | | | YES | NULL |
| search | 1 | client_id_index | 1 | client_id | A | 18 | NULL | NULL | | BTREE | | | YES | NULL |
| search | 1 | created_to_date | 1 | NULL | A | 68 | NULL | NULL | YES | BTREE | | | YES | cast(`created` as date) |
+--------+------------+------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+-------------------------+
11 rows in set (0.02 sec)
mysql> show index from email_leads;
+-------------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| email_leads | 0 | PRIMARY | 1 | id | A | 21340 | NULL | NULL | | BTREE | | | YES | NULL |
| email_leads | 1 | from_email_index | 1 | from_email | A | 5211 | NULL | NULL | | BTREE | | | YES | NULL |
| email_leads | 1 | base_id_index | 1 | base_id | A | 1482 | NULL | NULL | | BTREE | | | YES | NULL |
| email_leads | 1 | client_id_index | 1 | client_id | A | 3 | NULL | NULL | | BTREE | | | YES | NULL |
+-------------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.00 sec)
The explain output for the query:
+----+-------------+-------+------------+------+-----------------+---------------+---------+----------------------+-------+----------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-----------------+---------------+---------+----------------------+-------+----------+----------------------------------------------+
| 1 | SIMPLE | sh | NULL | ALL | created_to_date | NULL | NULL | NULL | 87659 | 50.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | el | NULL | ref | base_id_index | base_id_index | 98 | srmanager.sh.base_id | 14 | 100.00 | NULL |
+----+-------------+-------+------------+------+-----------------+---------------+---------+----------------------+-------+----------+----------------------------------------------+
Show create table output:
| search | CREATE TABLE `search` (
`id` varchar(32) NOT NULL,
`app_id` smallint NOT NULL,
`client_id` varchar(32) NOT NULL,
`base_id` varchar(32) NOT NULL,
`result_cnt` int NOT NULL,
`created` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
`office_connector` varchar(255) DEFAULT 'all',
`search_type` varchar(15) DEFAULT NULL,
`bedrooms` varchar(300) DEFAULT 'all',
`bathrooms` varchar(300) DEFAULT 'all',
`neighborhoods` text,
`min_price` int DEFAULT '0',
`max_price` int DEFAULT '99999',
PRIMARY KEY (`id`),
KEY `app_id_index` (`app_id`),
KEY `search_type_index` (`search_type`),
KEY `office_connector_index` (`office_connector`),
KEY `bedrooms_index` (`bedrooms`),
KEY `bathrooms_index` (`bathrooms`),
KEY `min_price_index` (`min_price`),
KEY `max_price_index` (`max_price`),
KEY `base_id_index` (`base_id`),
KEY `client_id_index` (`client_id`),
KEY `created_to_date` ((cast(`created` as date)))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 |
| email_leads | CREATE TABLE `email_leads` (
`id` varchar(32) NOT NULL,
`from_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`from_email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`base_id` varchar(32) NOT NULL DEFAULT '',
`client_id` varchar(32) NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `from_email_index` (`from_email`),
KEY `base_id_index` (`base_id`),
KEY `client_id_index` (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 |