【发布时间】:2020-02-27 17:24:01
【问题描述】:
我有以下永远运行的查询,我正在寻找是否有任何可以优化它的方法。这是在一个总共有 1,406,480 行数据的表上运行的,但除了 Filename 和 Refcolumn 之外,ID 和 End_Date 都已被索引。
我的查询:
INSERT INTO UniqueIDs
(
SELECT
T1.ID
FROM
master_table T1
LEFT JOIN
master_table T2
ON
(
T1.Ref_No = T2.Ref_No
AND
T1.End_Date = T2.End_Date
AND
T1.Filename = T2.Filename
AND
T1.ID > T2.ID
)
WHERE T2.ID IS NULL
AND
LENGTH(T1.Ref_No) BETWEEN 5 AND 10
)
;
不索引 Ref_No 的原因是这是一个文本列,因此当我尝试为该列建立索引时出现 BLOB/TEXT 错误。
如果有人能建议我如何加快这个查询,我将不胜感激。
谢谢
感谢 Bill 在多列索引方面我已经取得了一些进展。我首先运行了这段代码:
CREATE INDEX I_DELETE_DUPS ON master_table(id, End_Date);
然后我添加了一个新列来显示 Ref_No 的长度,但由于我的 MySQL 版本是 5.5,因此必须从 Bill 提到的查询中更改它。所以我分 3 步运行它:
ALTER TABLE master_table
ADD COLUMN Ref_No_length SMALLINT UNSIGNED;
UPDATE master_table SET Ref_No_length = LENGTH(Ref_No);
ALTER TABLE master_table ADD INDEX (Ref_No_length);
最后一步是使用 where 子句更改插入查询的长度。改为:
AND t1.Ref_No_length between 5 and 10;
然后我运行了这个查询,并在 15 分钟内将价值 280k 的 id 插入到我的 UniqueIDs 表中。我确实去更改了我的插入脚本,看看是否可以通过执行以下操作为长度添加更多值:
AND t1.Ref_No_length IN (5,6,7,8,9,10,13);
这是为了引入长度也等于 13 的值。这个查询花费了更长的时间,准确地说是 2 小时 50 分钟,但是查找所有长度为 13 的行的额外要求给了我额外的 700k唯一 ID。
我正在寻找使用 IN 子句优化查询的方法,但在此查询保持运行 24 小时的情况下,这是一个很大的改进。非常感谢比尔。
【问题讨论】:
-
长度函数很不幸,因为它禁止使用索引。如果 ref no 是整数,则存在明显的改进
-
(“发送数据”是一个无用的非信息。)
-
Michael,并且 t1.Ref_No_length 在 5 到 13 之间;而不是使用跳过 11 和 12 的 IN 列表可能会更快完成。