I have a simple select query which earlier in mysql 5.7 version used to work in 850 ms is now taking 2.20 seconds to run.
SELECT c.id,
c.cart_type as cartType,
c.name,
c.storefront_id as storefrontId,
c.contact_id as contactId,
c.account_number as accountNumber,
c.ship_to as shipTo,
c.name1 as shipToName1,
c.name2 as shipToName2,
c.city,
c.country,
c.status,
c.order_type as orderType,
c.currency as currency,
c.updated_at as updatedOn,
CASE WHEN EXISTS (SELECT 1
FROM contact_active_cart cac
WHERE cac.cart_id = c.id) THEN 'true' ELSE 'false' END as isActive
FROM (SELECT id
FROM cart c
WHERE c.cart_type = 'cart'
AND c.storefront_id = 1
AND c.status IN (
7, 8, 6, 2, 0
)
AND c.account_number in (
'0100000106', '0100000212', '0100000806', '0100000860', '0100001329', '0100001537', '0100010879', '0100012479', '0100012553', '0100012579'
)
ORDER BY created_at ASC
LIMIT 0,
200 ) as cart_inner_subselect
INNER JOIN cart c ON cart_inner_subselect.id = c.id;
Adding create table on request:
CREATE TABLE `cart` (
`id` bigint NOT NULL AUTO_INCREMENT,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`contact_id` varchar(255) NOT NULL,
`storefront_id` bigint NOT NULL,
`cart_type` varchar(50) DEFAULT NULL,
`status` tinyint(1) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`ship_to` varchar(255) NOT NULL,
`account_number` varchar(40) DEFAULT NULL,
`name1` varchar(35) DEFAULT NULL,
`name2` varchar(35) DEFAULT NULL, `city` varchar(35) DEFAULT NULL,
`state` varchar(80) DEFAULT NULL,
`country` varchar(80) DEFAULT NULL,
`order_type` varchar(5) DEFAULT NULL,
`currency` varchar(3) DEFAULT NULL
PRIMARY KEY (`id`),
UNIQUE KEY `uk-cart` (`contact_id`,`storefront_id`,`name`,`cart_type`,`submission_datetime`),
KEY `idx-cart-cart_type` (`cart_type`),
KEY `idx-cart-cart_overview_1` (`cart_type`,`storefront_id`,`status`,`account_number`,`created_at`),
KEY `idx-cart-cart_overview_contact` (`cart_type`,`storefront_id`,`status`,`account_number`,`contact_id`,`created_at`),
KEY `idx-cart-cart_overview_shipTo` (`cart_type`,`storefront_id`,`status`,`account_number`,`ship_to`,`created_at`),
KEY `idx-cart-cart_overview_all` (`cart_type`,`storefront_id`,`status`,`account_number`,`contact_id`,`ship_to`,`created_at`)
) ENGINE=InnoDB AUTO_INCREMENT=24331499 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `contact_active_cart` (
`contact_id` varchar(255) NOT NULL,
`cart_id` bigint NOT NULL,
`storefront_id` bigint NOT NULL,
PRIMARY KEY (`contact_id`,`storefront_id`),
KEY `idx-contact_active_cart-cart_id` (`cart_id`),
KEY `idx-contact_active_cart-contact_id` (`contact_id`),
KEY `idx-contact_active_cart-storefront_id` (`storefront_id`),
CONSTRAINT `contact_active_cart_FK` FOREIGN KEY (`cart_id`) REFERENCES `cart` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
I have added an index on cart_type, storefront_id, status, account_number. So, when i used to run this on version 5.7 the index was being picked up correctly while in 8.0 it is not picking up and the time taken is way higher than previously.
The data in say the cart table is around 600M. Please suggest any improvements or should i upgrade to any higher version in order to see any performance improvement.
In addition to the ask for checking the explain: I tried adding created_at in the index i was using (index idx-cart-cart_overview_1). it reduced the time but still the time taken is higher than what i was getting in version 5.7. Also, if i add any additional filters in the where clause say contact_id or ship_to it is totally ignoring the indexes that should be used and refers idx-cart-cart_type using and the response time increases
In really can't see why you need the subquuery, it is superfluous
As you can see the query becomes instant quicker.
The number of indexes seems on the first glance excessive, you should see with other explains if they are all needed.
fiddle