MySQL UPDATE 性能...更快

标签 mysql performance query-performance

假设我有以下 2 个 MySQL 表:

CREATE TABLE Table1
(
    IndexNumber INT UNSIGNED NOT NULL AUTO_INCREMENT,
    FieldOne TINYINT UNSIGNED NOT NULL,
    FieldTwo VARCHAR(180) NOT NULL,
    FieldThree DATE,
    FieldFour INT,
    PRIMARY KEY (IndexNumber, FieldThree),
    UNIQUE KEY (FieldOne, FieldTwo)
) ENGINE=InnoDB;

CREATE TABLE Table2
(
    IndexNumber INT UNSIGNED NOT NULL,
    FieldFive TINYINT UNSIGNED NOT NULL,
    FieldSix TINYINT UNSIGNED NOT NULL,
    FOREIGN KEY (IndexNumber) REFERENCES Table1 (IndexNumber),
    KEY (IndexNumber),
    KEY (FieldFive, FieldSix)
) ENGINE=InnoDB;

现在,我想做几个查询来检索一些匹配的记录,并且在每个 SELECT 查询之后我想更新匹配的记录,以便明天之前不会再次检索它们。

SELECT 查询如下:

SELECT table1.fieldone, 
       table1.fieldtwo 
FROM   table2 
       INNER JOIN table1 
               ON table2.indexnumber = table1.indexnumber 
WHERE  table2.fieldfive = 1 
       AND table2.fieldsix = 2; 

SELECT table1.fieldone, 
       table1.fieldtwo 
FROM   table2 
       INNER JOIN table1 
               ON table2.indexnumber = table1.indexnumber 
WHERE  table2.fieldfive = 1 
       AND table2.fieldsix = 3 
       AND table1.fieldthree <> Curdate(); 

我的问题是 - 在每个选择查询之后更新匹配记录以使下一个 SELECT 查询不匹配的最快方法是什么?

我可以在 SELECT 查询中检索“IndexNumber”字段,然后我可以按如下方式执行 UPDATE 查询,传入“IndexNumber”字段值:

UPDATE table1 
SET    fieldthree = Curdate(), 
       fieldfour = (fieldfour + 1) 
WHERE  indexnumber IN (...indexnumbers...)ve = 1 
AND    table2.fieldsix = 3 
AND    table1.fieldthree <> curdate();

或者我可以重复 SELECT 查询中的 WHERE 并希望缓存使其更快:

UPDATE table2 
       INNER JOIN table1 
               ON table2.indexnumber = table1.indexnumber 
SET    table1.fieldthree = Curdate(), 
       table1.fieldfour = ( table1.fieldfour + 1 ) 
WHERE  table2.fieldfive = 1 
       AND table2.fieldsix = 2; 

UPDATE table2 
       INNER JOIN table1 
               ON table2.indexnumber = table1.indexnumber 
SET    table1.fieldthree = Curdate(), 
       table1.fieldfour = ( table1.fieldfour + 1 ) 
WHERE  table2.fieldfive = 1 
       AND table2.fieldsix = 3 
       AND table1.fieldthree <> Curdate() 
       AND table1.fieldthree <> Curdate(); 

请注意,UPDATE 查询将在 SELECT 查询之后、执行下一个 SELECT 查询之前立即执行。

这两种方法哪一种更有效?

最佳答案

首先,当你有id .. AUTO_INCREMENT时在InnoDB表中,PRIMARY KEY(id)之间没有区别和PRIMARY KEY(id, other_col) .

第二,你的table2没有明确的PRIMARY KEY ;这不好'。我们将为您提供一个隐藏的 PK,但它不会像您明确拥有自己的 PK 那样“好”。

对于此选择:

    INNER JOIN  table1  ON table2.indexnumber = table1.indexnumber
    WHERE  table2.fieldfive = 1
      AND  table2.fieldsix = 2;

将以 table2 开头因为有过滤( WHERE )。最优指标为

table2:  INDEX(fieldfive, fieldsix,   -- in either order
               indexnumber)           -- to make the index "covering"
table1:   (indexnumber)               -- it's already the PK, so good

对于此选择:

    INNER JOIN  table1  ON table2.indexnumber = table1.indexnumber
    WHERE  table2.fieldfive = 1
      AND  table2.fieldsix = 3
      AND  table1.fieldthree <> Curdate();  -- not easy to optimize

同样,它将从table2开始,并且与上面相同的索引是最佳的。另请注意...因为 table1 中最多有 1 行对于给定的indexnumber (当 JOINing 时),所有 <>要做的就是过滤掉一些行。 不需要调整任何索引。

(您的第一个 UPDATE 无效,因为它提到 fieldsix 而没有提及 table2 。)

第二个UPDATE讨论 SELECT 几乎涵盖了这些内容.

第三个UPDATE由于日期测试,可能会命中较少的行,但这意味着它与第二个 UPDATE 不同。 -- 因为它不会总是递增 fieldfour .

关于MySQL UPDATE 性能...更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51844905/

相关文章:

php - Laravel 代码仅在开发工具打开时才工作

php - 不将数据插入 wp_users 表中的自定义字段

mysql - 如何做这个sql查询?

performance - 当跨实体组 (XG) 事务实际上只命中一个实体组时,它是否会产生开销?

sql - 改进连接查询 postgresql/postgis

postgresql - 如何加速分区表的服务器端聚合

mysql - 通过 Liquibase 重命名主键列,自动增量被删除(MySQL)

performance - Chromium 自定义构建运行速度太慢

javascript - 如何高性能地从两个数组中提取子数组?

php - 添加where条件时mysql查询不起作用