Rah*_*hul 5 mysql performance optimization query-performance
我有一个 mysql 查询,它在 4 秒内返回结果。
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192
ORDER BY id DESC limit 10;
Run Code Online (Sandbox Code Playgroud)
但是当我向现有参数添加额外的 where 参数时,大约需要 30 秒才能完成。
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192 AND type = 'case'
AND fieldName = 'statusCode'
AND typesKey=5
ORDER BY id DESC limit 10;
Run Code Online (Sandbox Code Playgroud)
因此,我通过运行检查同一张表中的索引 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 是 BTREE xercasehistory 1 xecasehistory_active_govtId 1 活动 A 2 BTREE xercasehistory 1 xecasehistory_active_govtId 2 govtId A 39336 BTREE xercasehistory 1 xecasehistory_type 1 A 型 7721 BTREE xercasehistory 1 xercasehistory_entryDate 1 entryDate A 24545933 BTREE xercasehistory 1 xercasehistory_fieldName 1 fieldName A 14304 是 BTREE xercasehistory 1 xercasehistory_recordTable 1 recordTable A 11406 是 BTREE xercasehistory 1 xerId 1 xerId A 47113 是 BTREE xercasehistory 1 govtId 1 govtId A 34329 BTREE
我们可以在 where 子句 (xerId,type,type,typesKey) 中使用的所有字段中看到一个索引。现在的问题是我期待更短的等待时间,因为它已经过滤了数据,xerId = 192所以剩余的 where 条件应该对已经过滤的记录起作用xerId = 192。请帮忙
的输出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
Run Code Online (Sandbox Code Playgroud)
解释第一次查询的结果
id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra '1', 'SIMPLE', 'xercasehistory', 'ref', 'xerId', 'xerId', '5', 'const', '1256458', '使用地点'
解释第二个查询的结果
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', '使用索引条件; 使用 where'
对于第一个查询:
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192
ORDER BY
id DESC
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
如果表是 InnoDB,则需要在(xerId, id)- 上建立索引。(xerId)对于如此简单且返回不超过 10 行的查询来说,四秒是一个非常长的时间。添加该索引并重试。查询时间应降至几毫秒。
对于第二个查询:
SELECT
*
FROM
xercasehistory
WHERE
xerId = 192
AND type = 'case'
AND fieldName = 'statusCode'
AND typesKey = 5
ORDER BY
id DESC
LIMIT 10 ;
Run Code Online (Sandbox Code Playgroud)
相同的索引会很有用。如果使用相同索引的此查询的效率不是很高(几毫秒),则可能有许多(数千)行与索引 ( xerId = 192) 匹配,但与所有 4 个条件匹配的行并不多,因此更合适的索引(在所有4 列 + id) 会更有效。
至于:
我们可以在where子句中使用的所有字段中看到索引(xerId,type,type,typesKey)...
不,没有综合索引。每列有 4 个索引。
为什么(xerId)不使用索引,至少对于第一个查询来说很奇怪。我会将其替换为索引(xerId, Id),然后检查 EXPLAIN 输出。
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |