I have a mysql query which return results in 4 seconds.
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192
ORDER BY id DESC limit 10;
But when I add extra where parameters to the existing one the it is taking 30 seconds approx to complete.
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192 AND type = 'case'
AND fieldName = 'statusCode'
AND typesKey=5
ORDER BY id DESC limit 10;
So, I check the indexes from on same table by running show indexes from xercasehistory
xercasehistory 0 PRIMARY 1 id A 24545933 BTREE xercasehistory 1 xecasehistory_caseId_IDX 1 caseId A 2045494 BTREE xercasehistory 1 xecasehistory_typeskey 1 typesKey A 20169 YES BTREE xercasehistory 1 xecasehistory_active_govtId 1 active A 2 BTREE xercasehistory 1 xecasehistory_active_govtId 2 govtId A 39336 BTREE xercasehistory 1 xecasehistory_type 1 type A 7721 BTREE xercasehistory 1 xercasehistory_entryDate 1 entryDate A 24545933 BTREE xercasehistory 1 xercasehistory_fieldName 1 fieldName A 14304 YES BTREE xercasehistory 1 xercasehistory_recordTable 1 recordTable A 11406 YES BTREE xercasehistory 1 xerId 1 xerId A 47113 YES BTREE xercasehistory 1 govtId 1 govtId A 34329 BTREE
We can see an index in all fields used in where clause (xerId,type,type,typesKey ). Now the question is I was expecting a shorter wait time because it already filter data from xerId = 192
so the remaining where conditions should work on records already filtered by xerId = 192
. Please help
Output of SHOW CREATE TABLE xercasehistory;
:
CREATE TABLE `xercasehistory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`govtId` int(11) NOT NULL DEFAULT '0',
`caseId` int(11) NOT NULL DEFAULT '0',
`type` varchar(100) NOT NULL DEFAULT '',
`notes` text NOT NULL,
`entryDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`employeeId` int(11) NOT NULL DEFAULT '0',
`typesKey` int(7) DEFAULT '0',
`logLevel` int(11) NOT NULL DEFAULT '1000',
`dataType` int(11) NOT NULL DEFAULT '0',
`recordTable` varchar(100) DEFAULT NULL,
`old_recordId` int(11) DEFAULT NULL,
`new_recordId` int(11) DEFAULT NULL,
`fieldName` varchar(100) DEFAULT NULL,
`old_int` int(11) DEFAULT NULL,
`old_varchar` varchar(255) DEFAULT NULL,
`old_text` text,
`old_float` float DEFAULT NULL,
`old_date` datetime DEFAULT NULL,
`new_int` int(11) DEFAULT NULL,
`new_varchar` varchar(255) DEFAULT NULL,
`new_text` text,
`new_float` float DEFAULT NULL,
`new_date` datetime DEFAULT NULL,
`more_details` tinyint(4) NOT NULL DEFAULT '0',
`active` tinyint(4) NOT NULL DEFAULT '1',
`xerId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `xecasehistory_caseId_IDX` (`caseId`),
KEY `xecasehistory_typeskey` (`typesKey`),
KEY `xecasehistory_active_govtId` (`active`,`govtId`),
KEY `xecasehistory_type` (`type`),
KEY `xercasehistory_entryDate` (`entryDate`),
KEY `xercasehistory_fieldName` (`fieldName`),
KEY `xercasehistory_recordTable` (`recordTable`),
KEY `xerId` (`xerId`),
KEY `govtId` (`govtId`)
) ENGINE=InnoDB AUTO_INCREMENT=29726001 DEFAULT CHARSET=latin1
Explain result for first query
id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra '1', 'SIMPLE', 'xercasehistory', 'ref', 'xerId', 'xerId', '5', 'const', '1256458', 'Using where'
Explain result for second query
id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra '1', 'SIMPLE', 'xercasehistory', 'range', 'xecasehistory_typeskey,xecasehistory_type,xercasehistory_fieldName,xerId', 'xerId', '5', NULL, '1256458', 'Using index condition; Using where'
Best Answer
For the first query:
you need an index on
(xerId, id)
- or just on(xerId)
if the table is InnoDB. Four seconds is a very long time for a query that is so simple and returns no more than 10 rows. Add this index and try again. Query time should drop to a few milliseconds.For the second query:
the same index would be useful. If efficiency is not superb (a few milliseconds) for this query with the same index, you may have many (thousands) rows that match the index (
xerId = 192
) but not so many that match all 4 conditions, so a more appropriate index (on all 4 columns + theid
) would be more efficient.As for:
No, there isn't a composite index. Theer are 4 indexes, on each column separately.
Why the
(xerId)
index is not used, at least for the first query is weird though. I would replace it with an index on(xerId, Id)
and check the EXPLAIN output after that.