MySQL UPDATE性能...更快

时间:2018-08-14 15:26:46

标签: 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查询执行之前立即执行。

这两种方法中哪个更有效?

1 个答案:

答案 0 :(得分:0)

首先,当InnoDB表中有id .. AUTO_INCREMENT时,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开头,并且与上述相同的索引是最佳的。另一个注意事项...由于给定的table1indexnumber中最多有1行(当JOINing时),所有<>所要做的就是过滤掉一些行。 无需调整任何索引。

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

讨论UPDATE几乎涵盖了第二个SELECT

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

相关问题