【问题标题】:MYSQL : Left outer join sql takes long timeMYSQL:左外连接sql需要很长时间
【发布时间】:2012-11-08 17:36:11
【问题描述】:

我有这个查询,执行时需要很长时间

SELECT DISTINCT ticket.`id`, 
                `sender`, 
                `text`, 
                `receivedtime`, 
                `priorityid`, 
                `cityid`, 
                `categoryid`, 
                `statusid`, 
                `activeuserid`, 
                `note`, 
                `operationid`, 
                '' AS SMSHistory, 
                '' AS replySMS, 
                '' AS ticketHistory 
FROM   `ticket` 
       LEFT OUTER JOIN tickethistory 
                    ON tickethistory.ticketid = ticket.id 
       LEFT OUTER JOIN users 
                    ON tickethistory.uid = users.uid 
ORDER  BY ticket.`id` DESC 
LIMIT  0, 50 

这是表结构:

门票:

CREATE TABLE   `ticket` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `sender` varchar(50) NOT NULL,
    `text` text NOT NULL,
    `receivedTime` datetime NOT NULL,
    `priorityId` int(10) NOT NULL,
    `cityId` int(10) NOT NULL,
    `categoryId` int(10) NOT NULL,
    `statusId` int(10) NOT NULL,
    `activeUserId` int(11) NOT NULL,
    `note` text NOT NULL,
    `operationId` int(10) NOT NULL,
    `gateway` varchar(80) NOT NULL,
    KEY `Index 1` (`id`),
    KEY `sender` (`sender`),
    KEY `priorityId` (`priorityId`),
    KEY `cityId` (`cityId`),
    KEY `categoryId` (`categoryId`),
    KEY `statusId` (`statusId`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

  ----

机票历史:

  CREATE TABLE   `tickethistory` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `ticketId` int(10) NOT NULL,
    `uid` int(11) NOT NULL,
    `actionId` int(10) NOT NULL,
    `time` datetime NOT NULL,
    `param1` text NOT NULL,
    `param2` text NOT NULL,
    `param3` text NOT NULL,
    KEY `Index 1` (`id`),
    KEY `ticketId` (`ticketId`),
    KEY `uid` (`uid`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

  ---- 

用户:

CREATE TABLE IF NOT EXISTS `users` (
  `Uid` int(11) NOT NULL AUTO_INCREMENT,
  `UserName` varchar(255) NOT NULL,
  `Upassword` varchar(32) NOT NULL,
  `UName` text NOT NULL,
  `Ucountry` text NOT NULL,
  `Umobile` varchar(255) NOT NULL,
  `UregisterDate` date NOT NULL DEFAULT '0000-00-00',
  `Ugroup` char(1) NOT NULL DEFAULT 'U',
  `Usender` varchar(11) NOT NULL DEFAULT 'SMS',
  `Ucredits` decimal(11,2) NOT NULL DEFAULT '0.00',
  `Uemail` varchar(255) NOT NULL,
  `CreditUpdatedDate` date DEFAULT NULL,
  `USMSC` varchar(30) NOT NULL,
  `repeatedDuration` int(10) DEFAULT '0',
  `langid` varchar(10) DEFAULT 'Ar',
  `parentId` int(11) NOT NULL DEFAULT '0',
  `Usess` varchar(255) NOT NULL DEFAULT '0',
  PRIMARY KEY (`Uid`),
  UNIQUE KEY `UserName` (`UserName`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

这里是解释命令的结果:

  'id';'select_type';'table';'type';'possible_keys';'key';'key_len';'ref';'rows';'Extra'
  '1';'SIMPLE';'ticket';'ALL';'';'';'';'';'348580';'Using temporary; Using filesort'
  '1';'SIMPLE';'tickethistory';'ref';'ticketId';'ticketId';'4';'ticket.id';'2';'Distinct'
  '1';'SIMPLE';'users';'eq_ref';'PRIMARY';'PRIMARY';'4';'tickethistory.uid';'1';'Using index; Distinct'

【问题讨论】:

  • @Ali 在创建小提琴时出错 --> 架构创建失败:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 14 行的“索引 1 (id)、KEY sender (sender)、KEY priorityId (priorityId)、KEY cityId”附近使用正确的语法:
  • 请同时包含users 表。还有一个建议:也许您想考虑将PRIMARY KEYid 列一起使用。 dev.mysql.com/doc/refman/5.5/en/optimizing-primary-keys.html
  • KEY Index 1 (id), KEY sender (sender), KEY priorityId (priorityId), KEY cityId (cityId), KEY @ 987654338@(categoryId),KEYstatusIdstatusId

标签: mysql sql optimization


【解决方案1】:

EXPLAIN 表明它使用临时表和文件排序来对 TICKET 表中的记录进行排序。这有点奇怪,因为您正在排序的 ID 上有一个索引,但鉴于它匹配 350K 记录,这可能就是它慢的原因。

当您尝试查找最新记录时,请尝试包含限制性“where”子句,例如将搜索限制在上周(不要忘记在 receivedTime 上创建索引)。

您可能还考虑没有从 ticketHistory 到 User 的外部连接 - UID 列不为 NULL,因此应该没有没有匹配用户的记录。

【讨论】:

  • 但我想做一个基于用户 UID 的搜索
  • 您发布的 SQL 中没有 UID 的“where”子句 - 那是不同查询的一部分吗?
猜你喜欢
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多