簡體   English   中英

進一步優化此查詢? - 索引但仍然緩慢

[英]Optimize this query further? - indexed but still slow

我在下面有一個查詢加入4個表。 我添加了索引,並且使用索引的解釋輸出看起來很好(見下文)。

我可以進一步優化查詢嗎?

modelXml在某些記錄上相當大。對於一個大型項目,我得到22條記錄,每條記錄大約有2.5-3MB的modelXml數據,查詢需要很長時間(總返回69MB的數據)。 我懷疑這是問題,但不知道如何處理它。 我正在閱讀調整內部mysql變量,例如key_buffer_size和table_cache。 這有什么幫助嗎?

key_buffer_size目前設置為8384512(~8MB),table_cache設置為64我應該將它增加到什么? 我應該考慮哪些其他變量來加速返回這些大數據?

歡迎任何其他建議。 我是mysql的新手,但我真的想要變得更好。

SELECT `m`.`modelId`, `m`.`modelTypeId`, `m`.`modelXml`, `m`.`xmlSize`, `m`.`createdById`, `m`.`creationDate`, `m`.`modifiedDate`, `u`.`firstName`, `u`.`lastName` FROM `models_1` AS `m` 
INNER JOIN `modelFolderAssociations_1` AS `mfa` ON m.modelId = mfa.modelIOId 
INNER JOIN `modelFolders_1` AS `mf` ON mfa.folderId = mf.folderId 
INNER JOIN `users_1` AS `u` ON m.createdById = u.userId 
WHERE (m.projectId = 2) AND (mfa.folderId = 5) AND (mfa.modelIOType = 2) AND (m.modelTypeId = 2)

CREATE TABLE `models` (
 `modelId` int(11) NOT NULL auto_increment,
 `customerId` int(11) NOT NULL,
 `groupId` int(11) NOT NULL,
 `projectId` int(11) NOT NULL,
 `createdById` int(11) NOT NULL,
 `modelTypeId` int(11) NOT NULL,
 `modelXml` longtext,
 `modelSpecXml` longtext NOT NULL,
 `xmlSize` bigint(20) NOT NULL default '0',
 `creationDate` datetime NOT NULL,
 `modifiedDate` datetime NOT NULL,
 PRIMARY KEY  (`modelId`,`customerId`)
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8 


CREATE TABLE `modelFolders` (
     `folderId` int(11) NOT NULL auto_increment,
     `customerId` int(11) NOT NULL,
     `groupId` int(11) NOT NULL,
     `projectId` int(11) NOT NULL,
     `parentId` int(11) NOT NULL,
     `folderName` varchar(64) NOT NULL,
     `folderType` int(11) NOT NULL,
     `editable` tinyint(1) NOT NULL default '1',
     `nextDefaultNameNumber` int(11) NOT NULL default '1',
     `creationDate` datetime NOT NULL,
     `modifiedDate` datetime NOT NULL,
     PRIMARY KEY  (`folderId`,`customerId`),
     KEY `parentId` (`parentId`)
    ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

CREATE TABLE `modelFolderAssociations` (
 `associationId` int(11) NOT NULL auto_increment,
 `customerId` int(11) NOT NULL,
 `folderId` int(11) NOT NULL,
 `projectId` int(11) NOT NULL,
 `modelIOId` int(11) NOT NULL,
 `modelIOType` tinyint(1) NOT NULL default '1',
 `creationDate` datetime NOT NULL,
 `modifiedDate` datetime NOT NULL,
 PRIMARY KEY  (`associationId`,`customerId`),
 KEY `folderId` (`folderId`,`modelIOType`)
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8

CREATE TABLE `users` (
 `userId` int(11) NOT NULL auto_increment,
 `customerId` int(11) NOT NULL,
 `userName` varchar(50) NOT NULL,
 `password` varchar(256) NOT NULL,
 `firstName` varchar(50) default NULL,
 `lastName` varchar(50) default NULL,
 `creationDate` datetime NOT NULL,
 `modifiedDate` datetime NOT NULL,
 PRIMARY KEY  (`userId`,`customerId`),
 UNIQUE KEY `userName` (`userName`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8

解釋輸出

+----+-------------+-------------------------+--------+---------------+----------+---------+---------------------------------------------------+------+-------------+
| id | select_type | table                   | type   | possible_keys | key      | key_len | ref                                               | rows | Extra       |
+----+-------------+-------------------------+--------+---------------+----------+---------+---------------------------------------------------+------+-------------+
|  1 | SIMPLE      | modelFolders            | const  | PRIMARY       | PRIMARY  | 8       | const,const                                       |    1 | Using index |
|  1 | SIMPLE      | modelFolderAssociations | ref    | folderId      | folderId | 5       | const,const                                       |   22 | Using where |
|  1 | SIMPLE      | models                  | eq_ref | PRIMARY       | PRIMARY  | 8       | xa_system.modelFolderAssociations.modelIOId,const |    1 | Using where |
|  1 | SIMPLE      | users                   | eq_ref | PRIMARY       | PRIMARY  | 8       | xa_system.models.createdById,const                |    1 |             |
+----+-------------+-------------------------+--------+---------------+----------+---------+---------------------------------------------------+------+-------------+

擁有大型文本列,就像您用來存儲我所假設的XML那樣,無論索引的結構如何,都會損害性能。

在這些情況下,可以更好地將文本列移動到單獨的表中,並按照您已經存儲的字符串長度和CRC32進行索引。

CREATE TABLE MODEL_XML (
 xmlId INT(11) unsigned NOT NULL auto_increment,
 xmlSize BIGINT(20) NOT NULL default '0',
 crc32 INT(11) unsigned NOT NULL,
 xmlData LONGTEXT,
 PRIMARY KEY (xmlId),
 UNIQUE KEY (xmlSize, crc32)
)

然后,表格中具有重要索引的列的寬度將保持不變。

恩。

modelXmlId INT(11) unsigned NOT NULL
specXmlId INT(11) unsigned NOT NULL

它還具有冗余文本(空字符串等)更節省空間的優點,因為它們將共享一個xmlId,因此在DB中共享一行。

您應該索引外鍵,這對您的連接有幫助:

CREATE INDEX IDX_MODELS_CUSTID
on models (customerId)

CREATE INDEX IDX_FLDR_ASSOC_MODELIO
modelFolderAssociations(modelIOId)


CREATE INDEX IDX_FLDR_ASSOC_FLDRID
modelFolderAssociations(folderId)

等等。

從SELECT子句中取出modelXml列后測試查詢。

如果速度明顯更好,則緩慢來自要傳輸的數據量,而不是查詢本身。

您的索引並不總是與查詢和聯接匹配。 如果WHERE和JOIN子句中的所有列都不在索引中,則會強制mysql查看基礎行,這將導致性能下降,尤其是因為模型行太寬。

對於“modelFolderAssociations”,您為where子句創建了正確的復合鍵,但是您應該為要建模的連接包含modelIOId。

對於“模型”,您需要(modelId,projectId,modelTypeId,createdById)上的復合索引來覆蓋來自mfa的傳入鏈接,where子句中的兩個項以及指向用戶的出站鏈接。

對於“modelFolders”和“users”,您可以在主鍵中包含傳入聯接。

引擎只會使用一個索引,因此添加額外的索引單個索引(如Mike所建議的)將不會那么好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM