【问题标题】:How to optimize a MySQL select with rows that do not have matching values in the other table如何使用在另一个表中没有匹配值的行来优化 MySQL 选择
【发布时间】:2020-10-10 02:24:29
【问题描述】:

这个问题和这个问题差不多:MySQL select rows that do not have matching column in other table;但是,那里的解决方案对于大型数据集并不实用。

此表有 ~120,000 行。

CREATE TABLE `tblTimers` (
  `TimerID` int(11) NOT NULL,
  `TaskID` int(11) NOT NULL,
  `UserID` int(11) NOT NULL,
  `StartDateTime` datetime NOT NULL,
  `dtStopTime` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `tblTimers`
  ADD PRIMARY KEY (`TimerID`);
ALTER TABLE `tblTimers`
  MODIFY `TimerID` int(11) NOT NULL AUTO_INCREMENT;

这个表有大约 70,000 行。

CREATE TABLE `tblWorkDays` (
  `WorkDayID` int(11) NOT NULL,
  `TaskID` int(11) NOT NULL,
  `UserID` int(11) NOT NULL,
  `WorkDayDate` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `tblWorkDays`
  ADD PRIMARY KEY (`WorkDayID`);

ALTER TABLE `tblWorkDays`
  MODIFY `WorkDayID` int(11) NOT NULL AUTO_INCREMENT;

tblWorkDays 每个 WorkDayDate 每个 UserID 每个 TaskID 应该有一行,但是由于一个错误,尽管这些天有计时器,但仍然缺少几个工作日;所以,我正在尝试创建一个报告,显示任何没有与之关联的工作日的计时器。

SELECT A.TimerID FROM tblTimers A
LEFT JOIN tblWorkDays B ON A.TaskID = B.TaskID AND A.UserID = B.UserID AND DATE(A.StartDateTime) = B.WorkDayDate
WHERE B.WorkDayID IS NULL

这样做会导致服务器超时;所以,我正在寻找是否有办法更有效地做到这一点?

【问题讨论】:

  • 与所有相关表的 SHOW CREATE TABLE 语句一样,关于查询性能的问题总是需要对给定查询的 EXPLAIN
  • @Strawberry 添加了 CREATE TABLE 语句。

标签: mysql query-optimization


【解决方案1】:

您要加入的列上没有任何索引,因此它必须对两个表进行全面扫描。尝试添加以下内容:

ALTER TABLE tblTimers ADD INDEX (TaskID, UserID);
ALTER TABLE tblWorkDays ADD INDEX (TaskID, UserID);

【讨论】:

  • 查询耗时 0.0031 秒……嗯,差别很大……
  • 一般来说,每当您连接大型表时,请确保您在连接中使用的列上有索引。
  • 谢谢。出于好奇,您不再使用、不经常使用或没有涵盖足够大的数据集以致于没有必要的索引是否存在明显的性能劣势?
  • 有开销,因为它们占用磁盘空间并且在您修改表数据时必须更新。
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 2012-06-13
  • 2012-05-11
  • 2022-09-23
相关资源
最近更新 更多