【问题标题】:Which update is faster using join or sequential?使用联接或顺序哪个更新更快?
【发布时间】:2012-11-11 05:12:27
【问题描述】:

这个问题是我的previous Question 要求在删除一行时更新同一个表。

我可以使用 Stored Procedure 而不是 trigger 或 nested-query 编写两个解决方案。

两者都使用辅助函数my_signal(msg)

Employee 表中删除员工的存储过程。

  • 拳头解决方案:在表中使用UPDATE行,无需连接操作
CREATE PROCEDURE delete_employee(IN dssn varchar(64))
BEGIN
    DECLARE empDesignation varchar(128);
    DECLARE empSsn         varchar(64);
    DECLARE empMssn        varchar(64);
     SELECT SSN, designation, MSSN  INTO empSsn, empDesignation, empMssn 
     FROM Employee 
     WHERE SSN = dssn;

   IF (empSsn IS NOT NULL) THEN
    CASE       
           WHEN empDesignation = 'OWNER' THEN 
               CALL my_signal('Error: OWNER can not deleted!');

           WHEN empDesignation = 'WORKER' THEN 
            DELETE FROM Employee WHERE SSN = empSsn;               

           WHEN empDesignation = 'BOSS' THEN 
               BEGIN 
                   UPDATE Employee
                   SET MSSN = empMssn
                   WHERE MSSN = empSsn;

                DELETE FROM Employee WHERE SSN = empSsn;                   

               END;
    END CASE;
   ELSE 
               CALL my_signal('Error: Not a valid row!');
   END IF;
END//  
  • 第二种解决方案:正如我在上一个问题中使用INNER JOIN 所建议的那样
CREATE PROCEDURE delete_employee(IN dssn varchar(64))
BEGIN
    DECLARE empDesignation varchar(128);
    DECLARE empSsn         varchar(64);
    DECLARE empMssn        varchar(64);
      SELECT SSN, designation, MSSN  INTO empSsn, empDesignation, empMssn 
      FROM Employee 
      WHERE SSN = dssn;

   IF (empSsn IS NOT NULL) THEN
       IF (empDesignation = 'OWNER') THEN 
        CALL my_signal('Error: OWNER can not deleted!');
       END IF;

       UPDATE `Employee` A INNER JOIN `Employee` B ON A.SSN= B.MSSN
       SET B.MSSN = A.MSSN WHERE A.SSN = empSsn;

       DELETE FROM `Employee` WHERE SSN = empSsn;
   ELSE 
       CALL my_signal('Error: Not a valid row!');
   END IF;    
END//

我读到here 说,使用 join 对 Efficient SELECT 是有效的。但是我的问题只包括一个表,我觉得我的解决方案(第一个)比第二个更有效,因为 join 会比较消耗内存。

如果Employee table 足够大,请建议我哪个更好更高效。 哪个更适合我?原因

编辑:我检查了只包含 7 行的小表,两种解决方案都需要相同的时间。

mysql> CALL delete_employee(4);
Query OK, 1 row affected (0.09 sec)

我知道 SQL 函数的行为是不确定的,因为表启发式。哪个选择更好?如果您知道如何进一步优化查询。

【问题讨论】:

标签: mysql query-optimization mysql-5.0


【解决方案1】:

经过一段时间的思考,我几乎可以肯定它没有什么不同,第一个解决方案可能会稍微慢一些,但在一个不可测量的维度上。

最初的意图是,第一个解决方案更快,因为您首先通过 id 获取数据并仅在必要时更新。

但是 MySQL 在内部在 UPDATE .. JOIN 语句中没有做任何其他事情,只是在内部做,因此可能也更有效。

您的第一个解决方案没有捕获默认情况 - 如果我既没有得到 WORKERBOSS 会发生什么?

您的执行时间(0.09 秒)也非常长,这无法用我目前对您的数据库的了解来解释。

你设置了索引吗?

编辑:

看了table structure you've posted here之后 我对结构本身提出了一些改进建议。

1. 存储integer values 时使用类型int。数据库可以更高效地处理整数方式

2. 为什么要自己生成SSN?在PRIMARY KEY 上使用auto_increment 处理起来要简单得多,并且在添加新员工时可以为您节省大量工作

ALTER TABLE `Employee`
    CHANGE `SSN` `SSN` int(11) NOT NULL AUTO_INCREMENT ,
    CHANGE `MSSN` `MSSN` int(11) DEFAULT NULL,
    ADD KEY `KEY_Employee_MSSN` ( `MSSN` );

3. 您是否使用该名称进行查找?如果是这样,它也需要是唯一的

ALTER TABLE `Employee`
    ADD UNIQUE KEY `UNI_KEY_Employee` ( `name` );

4.您有固定的指定范围吗? enum 强制输入为定义的值之一

ALTER TABLE `Employee`
    CHANGE `designation` `designation` ENUM( 'BOSS', 'WORKER' ) NOT NULL DEFAULT 'WORKER',
    ADD KEY `KEY_Employee_designation` ( `designation` );

最终结构

mysql> EXPLAIN `Employee`;

+-------------+-----------------------+------+-----+---------+----------------+
| Field       | Type                  | Null | Key | Default | Extra          |
+-------------+-----------------------+------+-----+---------+----------------+
| SSN         | int(11)               | NO   | PRI | NULL    | auto_increment |
| name        | varchar(64)           | YES  | UNI | NULL    |                |
| designation | enum('BOSS','WORKER') | NO   | MUL | WORKER  |                |
| MSSN        | int(11)               | YES  | MUL | NULL    |                |
+-------------+-----------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

【讨论】:

  • 这个Database 只包含七个元组!
猜你喜欢
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 2010-11-10
  • 2012-10-03
  • 2011-02-15
相关资源
最近更新 更多